Unity | 深入了解NavMeshAgent

Posted 米莱虾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity | 深入了解NavMeshAgent相关的知识,希望对你有一定的参考价值。

相关API链接及概况


下方是常规默认情况下 Navigation 中的 Bake(烘焙)情况,蓝色部分表示可以走。

我们可以看到,Bake有以下这些属性可以设置

下面我们来逐个介绍这些属性

1. Agent Radius

  • Agent Radius 用来控制实体的区域半径/距离,影响了导航网格与游戏世界中障碍物的远近。
  • 当把它的值设置的非常大的时候,就可以看到与障碍物的距离十分庞大。
  • 当把它的值设置的非常小的时候,就可以看到与障碍物的距离十分狭小,以至于不仅网格和物体的边界没有了,甚至物体内部都有了网格。
  • Unity中默认的值是0.5,我们通过改变值重新 Bake 来感受一下直观的变化。下面的值分别是0.5、9.5和0.1

2. Max Slop

  • 即最大斜率,当把它的值减小的时候,就只能处理非常平缓的斜坡;当值很大的时候,甚至能上到山的顶峰。一般的默认值就是45(下面分别用 7.8 和 51.2 的与 45 的做对比展示) 

3. Advanced

  • Advanced 中有高级设置,这里的 Voxel Size 值越大,保真度越低,可以认为简化了很多,导致网格中有一些地方不连通,play 时就会绕开不连通的地方并往目标前进。

下面加大它的值并做效果呈现

4. Min Region Area

  • 这个最小区域决定了能否在一些小区域放置网格,它的默认值为2,此时我的图中房顶上是有蓝色网格的,我们把值改为10,这样房顶区域就不再用蓝色网格。
  • 一般来说,如果游戏世界基本上是连续的,那么就不会有什么问题。我们反而可以增大它的值来减去一些零碎的东西,使得看上去更为简洁。

unity中NavMeshAgent有关知识

Unity中与自动寻路相关的组件主要有两个:NavMeshAgent (  又称导航网格代理 ),Off Mesh Link( 分离网格链接 )。这两个组件的作用与使用范围是不同的,我们唯一可以确定的是我们必须烘焙地形,产生NavMesh(导航网格)。因为导航网格决定我们的角色(带有导航网格代理的角色)活动的范围。NavMeshAgent组件需要附着寻路的角色身上,比如怪物,而OffMeshLink这个组件主要是用来构造寻路角色的寻路路径的某个部分,比如我们有时需要怪物在寻路过程中从一个固定的地方移动到另一个固定的地方,这将会在我下面的例子中清楚的看到。好了,甭废话了,让我们开始吧!


       首先,我们先来了解一下NavMeshAgent组件,这个组件是unity3d提供的寻路系统的核心组件。官方是这样解释的:The NavMeshAgent component is connection with pathfinding,and is the place to put information about how this agent navigates the NavMesh 。意思大致是这样的:NavMeshAgent组件是关于寻路的,它是一个用来存放代理周游导航网格的路径信息的平台。那么代理又是什么呢?原来,角色的移动是要依靠代理来做的,每一个附着这个组件在寻路的过程中都是利用代理进行的,这也就是这个组件为什么叫导航网格代理的原因。每一个你需要让它具有自动寻路功能的角色必须要附着这个组件,除非你利用其它的寻路算法,但那样做实在是太复杂了,因为考虑的情况太多了,然而Unity为我们提供了这样一个组件,我们为啥不用呢?我们先来举一个例子吧,这样学起来也好理解一些。

    

       在Inspector下,我们可以看到NavMeshAgent组件的各个属性:

    

        这几个属性我简单的解释一下:



        Radius:导航代理的半径,我们可以适当的调节一下这个值


        Speed :这个属性代表这个导航网格代理寻路时可以达到的最大速率


         Acceleration :加速度,表示代理的速度从0加速到Speed时的最大的加速度


         Angular Speed :最高的角速度


         Stopping distance : 制动距离,当代理据目的地的距离小于这个值时开始减速


         Auto Traverse OffMesh Link :自动移动并关闭OffMeshLinks,这个选项对于我们利用程序来操纵后面我要介绍的OffMeshLink很关键,


         Auto Repath   自动重新寻路,如果发现现有路径已失效,那么它将获得新的路径,这个选项我们一般将其勾选上


         Height  : 导航代理的高度。


        Base Offset : 基本偏移,我们可以通过调整这个变量来调整代理自身的包围盒


       Obstacle Avoidace Type  : 代理躲避的水平,一般我们选默认的High Quality就行了


       NavMesh Walkable :导航网格代理可以通过的网格层类型


       好了这些属性我们基本上知道了一点,但要真正理解它,我们还有很长的路要走。我们到头来是要用脚本来控制寻路的,也就是说我们必须掌握NavMeshAgent这个类,还是老办法,看文档吧,记住,文档我们必须看,这是我们学习新东西必须做的,那些出视频,出书的没一个不是从看文档开始的。


       我们看NavMeshAgent这个类,Unity菜单:help->Scripting Reference 。我们找到这个类,发现里面的变量和方法还不少呢。这次我不可能将其全部讲解到 , 因为有些我自己都没用过,所以我只讲解我们常用的:


       NavMeshAgent(导航网格代理组件所对应的类)


       假使我们的主角身上添加了一个导航网格组件,我们一般在脚本中这样定义NavMeshAgent类型的成员变量:


         private NavMeshAgent nma ;


        并在Start或Awake函数中实例化它:


         nma = gameObject.GetComponent();


       重要变量:
  

        1.destination


        我们可以这样对导航网格代理设置目的地:


         nma.destination = Vector3类型的值。相当于nma.SetDestination( Vector3类型的值 )


        2.stoppingDistance 


        这个与Inspector面板中的Stopping Distance对应,一下再不涉及与Inspector面板中的属性对应的变量


        3.velocity 


        导航网格代理周游时的实时速度,非常重要


        4.nextPosion


       顾名思义,也就是下一个位置,在Update函数中打印这个属性,你会发现打印出的结果与这个导航网格代理周游过的路径一致


        5.steeringTarget(只读)


        这个属性是相当重要的,它指的是导航网格代理在导航网格中周游时所经过的拐点,这对于制作寻路网游同步角色的Transform是相当重要的,因为导航网格的寻路路线是直线,我们只需将其寻路的拐点与旋转角度告诉给服务器端,有服务器端广播出去,然后再写一个执行Transform同步的脚本(是特制的)绑定在非角色玩家身上就可以了。


        6.desiredVelocity(只读)


        这个属性说实话我用的不多,指的是导航网格代理的期望速度,与其当前速度不是等价的。


        7.remainingDistance( 只读 )


       导航网格代理离目的地还剩的距离,如果其值为0,那么代理已经到达了目的地了,所以我们可一个这样判断一个导航网格代理是否到达了目的地:


       if( nma.remainingDistance == 0 ){
       //执行行为


        }


        8.isOnOffMeshLink


       导航网格代理当前的位置是否位于OffMeshLink,因为这个牵扯到了另一个组件,我会在后面说的


       重要方法:

 

        1.SetDestination( Vector3 v )



       设置目的地,与nma.destination = v一样的,你想怎么用都行,只是这个函数在设置目的地成功后返回***e,否则返回false,就只比调用属性多了一个返回值


        2.ActivateCurrentOffMeshLink( bool activated )


        返回值为空


        与OffMeshLink有关,当activated为***e激活OffMeshLink,后面会讲到的


         3.CompleteOffMeshLink ()


        让导航网格代理完成在OffMeshLink上的周游,后面会讲的


        4.Move( Vector3 v )


        让导航网格代理朝向量v的世界坐标系方向平移v的长度


       5.Stop()


      让导航网格代理停止寻路,但此寻路状态可以靠下面一个函数恢复到寻路状态,并且目的地也与上次一样

 
         6.Resume()


        恢复寻路状态,此时角色会在上一次执行了Stop函数停下来后恢复当时的状态,目的地为上一次的目的地


       这8个属性与Inspector面板上的各个属性并且和这6个函数我们一定要好熟练掌握,这关系到我们是否能熟练书写寻路脚本。还有一些函数我这里没有介绍,就留着读者自己研究研究吧。































































































































































以上是关于Unity | 深入了解NavMeshAgent的主要内容,如果未能解决你的问题,请参考以下文章

深入了解Unity中LineRenderer与TrailRenderer

Unity | 深入了解NavMeshAgent

深入科技腹地,了解编程开发——计算机科学体验营

unity3D:游戏分解之曲线

Unity3D热更新技术点——ToLua

IL2CPP 详解