寻路系统
⼀、寻路⽅式
路点寻路
单元格寻路
⽹格寻路
⼆、实现寻路⽅法
1. 确定寻路者
2. 烘培寻路路⾯按摩鞋垫
3. 程序实现寻路算法
1、实现寻路步骤
2. 烘培寻路⽹格
Unity2019:打开window->AI->Navigation⾯板;如下图
点击Bake完成⽹格路⾯的烘培。
3. 给需寻路的物体添加NavMeshAgent组件(Unity主要通过NavMeshAgent组件实现⾃动寻路的功能,⾓⾊添加NavMeshAgent组 件后,就可以在NavMesh寻路⽹格上寻最优路径到⽬标)
婴童车
选中物体,然后在属性⾯板中点击Add Component,搜索Nav Mesh Algent,添加此组件。
4. 给需要寻路的物体添加脚本
public class FindWayByNav : MonoBehaviour
{
public Transform target;
private NavMeshAgent nav;
private void Start()
{
nav =this.GetComponent<NavMeshAgent>();
无触点稳压电源//SetDestination⽅法即为寻路⽅法,参数为⽬标物体的三维向量
nav.SetDestination(target.position);
矿用运人车}
文具盒生产过程
}
2、代码测试
⽤以上代码进⾏测试结果如下:
因⽆法发布视频,所以实际效果可按⼀下例⼦⾃⾏测试
红⾊Cube为⽬标物体,黄⾊Sphere为寻路物体,图中浅蓝⾊路线为烘培的⽹格路线。
三、关于Navigation中属性的介绍
Cost:寻路区域消耗度,数值越⼤,从此寻路区域消耗越⼤。寻路物体在区域消耗数值⼀样的情况下,会选择最优(最近)路⾯寻路,但如果寻路区域的消耗数值不同,会根据消耗的数值,越⼩越最优进⾏寻路。
有关Nav Mesh Agent的属性等介绍,详情请参见官⽅说明
四、组件Nav Mesh Obstacle的使⽤
在物体(命名为寻路物体)的寻路过程当中,若是直接添加⼀个物体(命名为障碍物体)作为路线上的障碍,但是寻路物体在按照路线进⾏前进时,并不会受到障碍物体的阻挡,⽽是直接穿透过物体继续前⾏。 缩管加工
为解决此问题,我们就需要给障碍物体添加Nav Mesh Obstacle组件
添加此组件之后,可看到障碍物体有⼀个绿⾊边框的长⽅体框住了障碍物体,此时寻路物体再次前⾏就会受到障碍物体的阻挡,有关此组件中属性说明,请参见官⽅说明⽂档
五、组件Off Mesh Link的使⽤
当寻路物体需要到另⼀个地⾯时,⽽两个地⾯之间没有连接,那么在进⾏烘培⽹格路⾯时,并不会将两个路⾯上的⽹格路⾯连接起来,那么如图(忽略障碍物体)所⽰,
寻路物体就不能够到达另⼀块地⾯到达⽬标物体⾝边。
为解决此问题,有两种解决⽅案:
(1)、在两块路⾯之间再加⼀个⾯板,进⾏⽹格路⾯的烘培即可。
(2)、使⽤Off Mesh Link组件进⾏实现。
Off Mesh Link的使⽤⽅法:在两块路⾯上,分别添加两个空的物体,并为其中⼀个物体添加此组件,再设置此组件的属性,起始点和⽬标点,再进⾏⽹格路⾯的烘培即可,实际效果如下:
注意:两边地⾯上进⾏连接的点不能在烘培的蓝⾊⽹格之外,否则⽆效,且两点间的弧线为不加粗的!
温馨提⽰:使⽤此组件⽆法调节物体在两点间移动的速度,如需调节速度,建议使⽤第⼀种⽅法。
六、⽤代码实现勾选不同的寻路区域
GetComponent<NavMeshAgent>().areaMask=8;
寻路区域每⼀个区域都是2的幂,如下图所⽰,通过幂的数值进⾏设置
若是想要选择多条路径,则将幂的数值进⾏相加再赋予areaMask即可。
Everything->-1,Nothing->0
七、注意问题
避免重复计算(位置不变的话就不要重新计算)
即,如果需要寻的静态物体位置是保持不变得话,那就不需要将组件NavMeshAgent的SetDestination(Vector3 target)⽅法放在Update/(循环)中调⽤进⾏重复计算运⾏;
Unity寻路系统的动态碰撞有局限性