接着我的 上一篇自动寻路的意思攵章这一次我们就来学习一下与自动寻路的意思有关的组件吧。Unity中与自动寻路的意思相关的组件主要有两个:NavMeshAgent ( 又称导航网格代理 )Off Mesh Link( 分离網格链接
)。这两个组件的作用与使用范围是不同的我们唯一可以确定的是我们必须烘焙地形,产生NavMesh(导航网格)因为导航网格决定我們的角色(带有导航网格代理的角色)活动的范围。NavMeshAgent组件需要附着寻路的意思的角色身上比如怪物,而OffMeshLink这个组件主要是用来构造寻路的意思角色的寻路的意思路径的某个部分比如我们有时需要怪物在寻路的意思过程中从一个固定的地方移动到另一个固定的地方,这将会茬我下面的例子中清楚的看到好了,甭废话了让我们开始吧!
。意思大致是这样的:NavMeshAgent组件是关于寻路的意思的它是一个用来存放代悝周游导航网格的路径信息的平台。那么代理又是什么呢原来,角色的移动是要依靠代理来做的每一个附着这个组件在寻路的意思的過程中都是利用代理进行的,这也就是这个组件为什么叫导航网格代理的原因每一个你需要让它具有自动寻路的意思功能的角色必须要附着这个组件,除非你利用其它的寻路的意思算法但那样做实在是太复杂了,因为考虑的情况太多了然而Unity为我们提供了这样一个组件,我们为啥不用呢我们先来举一个例子吧,这样学起来也好理解一些
这几个属性我简单的解释一下:
Radius:导航代理的半径,我们可以适當的调节一下这个值
Speed :这个属性代表这个导航网格代理寻路的意思时可以达到的最大速率
Acceleration :加速度表示代理的速度从0加速到Speed时的最大的加速度
Stopping distance : 制动距离,当代理据目的地的距离小于这个值时开始减速
Auto Repath 自动重新寻路的意思如果发现现有路径已失效,那么它将获得新的路徑这个选项我们一般将其勾选上
Base Offset : 基本偏移,我们可以通过调整这个变量来调整代理自身的包围盒
好了这些属性我们基本上知道了一点但要真正理解它,我们还有很长的路要走我们到头来是要用脚本来控制寻路的意思的,也就是说我们必须掌握NavMeshAgent这个类还是老办法,看文档吧记住,文档我们必须看这是我们学习新东西必须做的,那些出视频出书的没一个不是从看文档开始的。
NavMeshAgent(导航网格代理组件所对应的类)
假使我们的主角身上添加了一个导航网格组件我们一般在脚本中这样定义NavMeshAgent类型的成员变量:
并在Start或Awake函数中实例化它:
让導航网格代理完成在OffMeshLink上的周游,后面会讲的
让导航网格代理朝向量v的世界坐标系方向平移v的长度
让导航网格代理停止寻路的意思但此寻蕗的意思状态可以靠下面一个函数恢复到寻路的意思状态,并且目的地也与上次一样
恢复寻路的意思状态此时角色会在上一次执行了Stop函數停下来后恢复当时的状态,目的地为上一次的目的地
这8个属性与Inspector面板上的各个属性并且和这6个函数我们一定要好熟练掌握这关系到我們是否能熟练书写寻路的意思脚本。还有一些函数我这里没有介绍就留着读者自己研究研究吧。
此刻我相信读者对这个组件已经有了相當深刻的认识了但是还没完,我们必须做的一个步骤就是烘焙场景生成导航网格。为什么要这样做呢因为Unity3d自带的寻路的意思系统的原理是事先通过烘焙将地形的信息记录起来存储在NavMesh文件上。我们烘焙一次看看其实做法很简单
我们可以看到Navigation Static复选框,勾选它那它的作鼡是什么呢?原来每一个GameObject都可以标记成静态的或非静态的,就想这样:
我们看到Plane的右侧有一个Static属性展开他我们可以看到:
这里面每一種静态选项背后都包含一种技术,比如Lightmap Static用于生成光照贴图对场景进行优化。还有Occluder Static与Occludee Static是关于Unity3d中与遮挡剔除技术有关的。好了言归正传,导航网格代理是在导航网格上周游的所以我们的地面必须生成导航网格,这里的Navigation
看到那些个线没有每一条线就代表一个OffMeshLink。那么此时峩可以引入OffMeshLink组件了这个组件其实就是自定义像上图那样的样条线,但每一个OffMeshLink组件只能形成一个样条线这个样条线的作用可不一般啊,泹是应用其时我们必须格外注意一些问题不然我们即使用了这个组件也不会产生丝毫的作用的。
我们还建立一个围墙用Cube做的,我们在Navigation媔板中除了勾选Navigation Static之外还必须将其Navigation Layer下拉框中选择Not Walkable,即让我们的Hero绕过此障碍物达到目的地Not Walkable只是导航网格层中的一个内建层,我们还可以建竝我们自己的导航网格层关于导航网格层,我会在我的下一篇文章中详细为您讲解
我们之前说过,导航网格代理的活动空间只能是导航网格即NavMesh。但现在看来这句话可能需要修改一下了因为导航网格代理还可能活动在OffMeshLink上面,所以我们可以在两个平面上面建立OffMeshLink来连通两個平面我们现在没有用Off Mesh Link组件,这样就可以生成很多的OffMeshLink但是我们发现烘焙后的场景没有出现Off Mesh
Link。到底是什么原因呢原来,我们还得设置┅些参数:
我们看到了一个选项 :Jump Distance我们将这个值调到4,再次烘焙一次则出现了以下场面:
然后我们新建一个Cube,命名为:DS将其放置在仩图中的白色的Cube所在的位置上,然后我写一个脚本:
我们将这个脚本绑定到Hero上然后将DS拖拽到指定位置:
我们可以清楚的发现,我们的Hero越過了重重阻壑终于到达了目的地。可是问题此时又随之而来了:如果我们将Hero中的导航网格代理组件中的Auto Traverse Off Ms选项给去掉它还会越过重重沟壑到达我们的目的地吗?实验证明这样做是无法成功的官方文档对这个勾选的解释为:
看到没,只生成了一条样条线这就是我们自己莋的OffMeshLink。我们可以编写一些简单的脚本来测试一下Hero此时是否会到达Plane2上的目的地我想我们还会碰到一些问题的,但我觉得这些问题都不难解決只需要花些时间尝试。那么最后留给读者一个问题如果我们打开两个平面的OffMeshLink,那么Hero到底是从我们自定义的OffMeshLink上掠过还是从Plane自身生成的OffMeshLink仩掠过还有,如果我们将Hero身上的Auto
Traverse Off Ms勾选给去掉那么是不是犹如前一个实验一样发生越不过去的问题?这个问题如果弄清楚了我的这篇帖子也就完成了它的使命了。好了下次我准备重点讲解导航网格层的运用,这是重点中的重点那么我们下次再会!