• 游戏思考17:寻路引擎recast和detour学习三:客户端角度学习(unity专题导航系统)(09/19)


    一、如何构建导航网格

    1)导航系统作用

    帮助角色进行AI智能移动:朝目标移动,绕过障碍物,上下台阶…

    2)导航系统包括

    ①导航网格(NavMesh):下图的蓝色地形,可以行走的表面
    ②导航网格代理组件(NavMesh Agent):模拟人物移动和寻路
    ③导航网格障碍物(NavMesh Obstacle):定义物体为障碍物,这样导航网格代理就能绕过障碍物进行路径的选择
    ④网格外链接(Off-Mesh Link):地形中间没有相连的话,两点可以跳跃
    在这里插入图片描述

    3)做一个简单的导航Demo

    • 步骤简短声明
      在这里插入图片描述

    (1)在Scene这个目录下构建一个场景叫NavigationDemo0502
    在这里插入图片描述
    (2)在场景新建一个地面(3D-Plane)

    在这里插入图片描述

    (3)打开navigation窗口(在AI的窗口里面)
    在这里插入图片描述
    会有个窗口
    在这里插入图片描述
    把平面这个obj设成静态的
    在这里插入图片描述
    进行烘焙
    在这里插入图片描述
    这样plane就会有蓝色的内容出现

    在这里插入图片描述
    (4)因为要模仿人物移动,这里用个柱体代替人物(右键创建个Cylinder)

    在这里插入图片描述
    (5)想要这个圆柱体移动,就给他添加一个Nav Mesh Agent 组件
    在这里插入图片描述
    (6)给这个圆柱体一个目标Cube(右键新建3D->Cube),改名为target
    在这里插入图片描述

    (7)创建脚本Script目录,新建C#脚本文件CharacterNavigationControl.cs,并把这段代码添加到Character身上,并修改这段代码
    在这里插入图片描述

    载入脚本包
    using UnityEngine.AI
    
    public class CharacterNavigationControl: MonoBehaviour
    {
    	//导航网格代理
    	public NaviMeshAgent _character;
    	
    	//坐标三元素
    	public Transform targetTransform;
    	void Start()
    	{
    		_character = this.GetComonent<NavMeshAgent>();
    		if(_character && targetTransform)
    		{
    			_character.destination = 	targetTransform.position;
    		}
    	}
    
    ]
    
    
    

    (8)绑定两个物体,character绑定在Character里面,Target放在 Target Transform里面

    在这里插入图片描述
    (9)这样自动就会从开始位置位移去Cube target的位置
    在这里插入图片描述

    二、当行网格烘焙与烘焙设置

    1)对应相关参数

    在这里插入图片描述

    2)参数讲解

    (1)Agent Radius 参考导航网格代理角色半径,代理角色中心位置与墙壁或窗台可接近的最小距离
    (2)Agent Height 参考导航网格代理角色高度,角色可到达的空间的最小高度(代表人物行走的高度)
    (3)Max Slope  代理角色可走上坡道的陡峭程度,小于这个度数的话,人物可以行走
    (4)Step  Height  代理角色可以踏上障碍物的高度,阶梯的高度设置(低于这个高度的台阶,人物就可以行走)
    (5)Drop Height  
    (6)Jump Distance
    --(5)和(6)都是网格外连接的设置
    (7)Min Region Area 最小烘焙大小(存在大于这个值的地区,就能烘焙出来网格)
    

    在这里插入图片描述
    在这里插入图片描述

    三、导航网格代理与自动巡逻角色

    1)导航网格代理

    (1)对应设置
    在这里插入图片描述

    Base offset  碰撞圆柱体相对于变换轴心点的偏移
    1)Steering 驾驶
    --Speed  最大移动速度(世界单位/秒),移动的速度
    --Angular Speed 最大旋转速度(度/秒),角度转换的速度 
    --Acceleration 最大加速度(世界单位/平方秒表示),比如说0到3.5这个速度过程是有一定加速度的
    --Stopping distance 当靠近目标位置的举例到达此值时,代理将终止
    --Auto Braking  启动此属性后,代理在到目标时将减速。对于巡逻等行为(这种情况下,代理在多个点之间平滑移动)应禁用此属性
    2)Obstacle Avoidance  避开障碍
    --Quality:障碍躲避质量,如果拥有大量代理,则可以通过降低障碍躲避质量来节省CPU时间。如果躲避设置为无,则只会解析碰撞,而不会常使主动躲避其他代理和障碍物。
    --Priority 优先级,执行障碍时,此代理将忽略优先级较低的代理,此值在0~99范围内,其中较低的数字表示较高的优先级(比如前面有两个障碍物,会躲避优先级比较高的障碍物)
    3)Path  Finding 路径寻找
    --Auto Traverse  OffMesh  Link :设置为true 可自动遍历网格外连接(Off-Mesh Link)。如果要使用动画或某种方式遍历网格外连接,则应关闭此功能
    --Auto Repath: 启用此属性后,代理将在到达部分路径末尾时常使再次寻路。当没有到达目标的路径时,将生成一条部分路径通向与目标最近的可达位置
    --Area Mask :Area Mask  描述了代理在寻路时将考虑的区域类型(Jump、Walkable、Not Walkable)
    若没有设置Jmp的网格,那只设置jump的话就没办法移动
    

    2)练习一:创建个巡逻的AI角色

    • 步骤
    1) 创建场景,添加Plane、Cube
    2) 使用Cube构建一个带台阶的地形
    3) 构建导航网格
    4) 创建Cylinder,添加NavMesh Agent组件
    5) 创建若干个Sphere,随机位置摆放
    6) 新建脚本MoveTo,设置Agent的destination,让角色在各个点巡逻
    

    1)创建多个target
    在这里插入图片描述
    2)编辑这个Character的脚本
    在这里插入图片描述

    using UnityEngine.AI
    
    public class CharacterNavigationControl: MonoBehaviour
    {
    	//导航网格代理
    	public NaviMeshAgent _character;
    	public Transform    targetTransformFather;
    	public Transform[]  targetTransforms;  //创建个目标数组
    	//坐标三元素
    	public Transform targetTransform;
    	
    	int destinationIndex = 0;
    	void Start()
    	{
    		targetTransform = targetTransformFather.GetComponentsInChildren<Transform>();
    		_character = this.GetComonent<NavMeshAgent>();
    		if(_character && targetTransform)
    		{
    			//开始的时候跟随第一个目标
    			_character.destination = 	targetTransforms[0].position;
    		}
    	}
    
    	void Update()
    	{
    		//表示不在计算过程中且已经到达目标就绪(!pathPending)
    		if(!_character.pathPending && _character.remainingDistance<0.5f)
    		{
    			//每次到下一个目标点
    			destinationIndex = (destinationIndex + 1) % targetTransforms.Length;
    			_character.destination = targetTransforms[destinationIndex].position;
    		}
    	}
    
    ]
    

    这里要设置father的Target
    在这里插入图片描述
    就会发现会找到所有transform
    在这里插入图片描述
    这样就能在各个目标间寻路

    在这里插入图片描述

    • 相关名词解释

    在这里插入图片描述

    3)练习二、构建一个朝目标位置移动的角色

    • 流程
    1)构建导航网格
    2)创建Capsule,添加NavMesh Agent组件
    3)新建脚本MousePointMove
    4)通过射线投射,获取涉嫌投射点,设置导航代理朝着投射点移动
    

    1)导航网格之前设置过
    2)构建一个3D的胶囊体并命名为player
    在这里插入图片描述
    3)新建脚本MousePointMove
    在这里插入图片描述
    把脚本拖到player上
    在这里插入图片描述

    public class MousePointMove:MonoBehaviour
    {
    	void Start()
    	{
    
    	}
    	
    	void Update()
    	{
    		//鼠标右键点击是1
    		if(Input.GetMouseButtonDown(1))
    		{	
    			//需要返回射线相交于地面的位置
    			RaycastHit hit;
    		
    			//从启示点到目标点发射一个射线
    			if(Physicd.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),out,hit,1000f))
    			{
    				this.GetComponent<NavMeshAgent>().destination = hit.point;
    			}
    		}
    	}
    }
    

    4)相机有点远的话就调整下相机的位置
    在这里插入图片描述
    设置相机斜角
    在这里插入图片描述
    鼠标右键点击就可以移动
    在这里插入图片描述
    可以调整下速度或上下坡,自动会根据导航网格寻路

    四、导航网格障碍物组件(Navmesh Obstacle,动态障碍物)

    1)概念介绍

    • 概念
      Unity用这个组件来定义障碍物。当障碍物移动时,导航网格会尽力避开,障碍物静止时,会在导航网格上留下一个不可移动的孔

    • 参数结束

    Carve: 雕刻,勾选后,导航网格障碍物会在导航网格中创建一个孔
    Move Threshold: 当导航网格的移动超过Move Threshold设置的值时,Unity会将其视为移动状态。
    使用此属性可设置该阈值举例来更新移动的雕刻孔洞
    Time To Stationary : 将障碍物视为精致状态所需等待时间(以秒为单位)
    Carve Only Stationary: 用此属性后,只有再静止状态时才会雕刻障碍物
    
    • 障碍物举例
      可以看到当前的这个方块体Cube是个障碍物,Cube四周的面都是灰色
      在这里插入图片描述
      设置这个Cube为Not Walkable时,再烘焙下,中间就不能走动
      在这里插入图片描述

    2)实现客户端动态障碍物

    (1)创建个Cube
    在这里插入图片描述
    (2)添加导航网格障碍物组件(做动态障碍物)

    在这里插入图片描述

    (3)选中Carve,自动在网格雕刻一个孔
    在这里插入图片描述

    五、网格外链接组件(Off-Mesh Link)

    1)组件作用

    连接两个没有相连行走表面的位置

    2)参数解释

    Start/End: 网格外链接两端位置的Transform
    Cost Override:  计算处理路径请求的路径成本,涉及到一些性能考虑
    Bi-Directional; 如果启用此属性,则可以再任意方向上遍历链接。否则,只能按照从Start到End的
    方向遍历链接(若取消只能从Start到End遍历)
    Activated: 到指定寻路器(pathfinder) 是否将使用此链接(不勾选的话,不能走这条路径)
    Auto Update Positions:  如果启用此属性,当端点移动时,网格外链接将重新链接到导航网格。如果禁用,即使移动了端点,链接也将保持其起始位置l(这个设置没啥大用)
    Navigation Area: 链接的导航区域类型(可选有很多,例如Walkable)
    

    3)网格外链接添加操作

    (1)给第一个平面添加网格外链接

    在这里插入图片描述
    (2)创建两个位置(起点和终点位置)

    在这里插入图片描述
    ①创建两个Cube在两个不同平面上

    在这里插入图片描述
    ②设置成静态的
    ③烘焙
    在这里插入图片描述
    ④两个Cube移动到网格外链接的Start和End
    在这里插入图片描述

    4)设置烘焙时自动生成网格外链接(并设置网格外连接的属性)

    ①勾选设置
    在这里插入图片描述
    ②在烘焙里面设置网格外链接的属性

    Drop Height   15  跳跃的高度
    Jump Distance 10 落下的距离
    

    当设置跳跃高度大于某个小物体的高度时,也会生成网格外连接(图中方块高度为10,跳跃高度为10.1,刚好能跳上去)
    在这里插入图片描述
    ③一般都是用网格外连接的组件去做网格外连接,因为自动生成会有很多不必要的外链接
    如图:
    在这里插入图片描述

  • 相关阅读:
    MyBatis 进阶
    【大模型】更强的开源可商用的中英文大语言模型baichuan2来了,从零开始搭建
    openlayers+vue的bug
    自接触svn之后对git的了解及其应用
    java项目使用GRPC框架
    LeetCode算法题解|LeetCode435. 无重叠区间、LeetCode763. 划分字母区间、LeetCode56. 合并区间
    深入了解队列数据结构:定义、特性和实际应用
    Lenovo Quick Fix:关闭或开启Win10系统的自动更新
    HCIP---VRRP
    最大似然估计,散度,交叉熵
  • 原文地址:https://blog.csdn.net/weixin_43679037/article/details/126880088