一个导航网格(也就是Navmesh)是世界几何体简化的表示法,被游戏代理用于在世界中进行导航。通常,代理(agent )有一个目标,或一个目的地,它试图找到一个路径,然后沿路径导航到达目标。这个过程被称为寻路。请注意,导航网格生成(或烘焙)是通过游戏开发者在编辑器内完成,而寻路是在运行时根据导航网格的代理来完成。
在复杂的游戏世界,可以有许多代理,动态的障碍,在世界不同地区不断变化的可达程度。代理需要对这些变化动态作出反应。代理的寻路任务可以被打断或者受到一些事情的影响,如与其他角色产生碰撞,改变地形的特征,物理障碍(如关门),那么到实际目的地的路径就会有所更新。
在烘焙过程中是否进行自动网格链接(off mesh link generation)也取决于导航烘焙设置中的Jump distance (跳高距离)和Drop height(掉落高度)属性。
导航网格层选择自动生成网格链接,默认是内置层Jump层。这可以控制全局进行自动网格链接的成本。
1、NavMeshAgent组件
导航网格代理(NavMesh Agent )组件用于寻路,是存放代理如何在导航网格(NavMesh)中导航的信息的地方。
Radius:代理的半径(这是代理的“个人遮护罩”,形成一个屏蔽罩,从而使其他代理无法通过此遮护罩)遮护罩可以形象的看成对象的collider
我为两个对象的Radius都设为了2.5,效果图如下:
那么右边的对象无论怎么走,也都是无法进入左边对象的遮护罩内的,也就是左边对象的绿色线内的!效果如下:
两个对象都是向同一个点移动,但是因为Radius“遮护罩”的原因,致使他们无法靠近,这就可以避免多个对象因为靠的太近造成乱象的情况!
当我们把Radius设为0.1时,就造成了下面的情况了:
Speed:速度,寻路的最大移动速度。代理通常需要在寻路时加速和减速(例如,在急转弯时它会减缓速度)。速度往往被限制于路径段的长度和花费在加速和刹车上的时间,但速度不会超过这个属性设定的值,即使是在很长一段直的路径上!
Acceleration:加速度: 作为寻路时代理的最大加速度,给出了 units / sec^2 。代理不能精确的跟随导航系统计算的路径线段,而是使用沿路径航点作为中间目标,此值是代理可以加速迈向下一个关键点的最大值。
Angular Speed: 角速度:寻路时的最大转动速度(度/秒)。这是在该代理能够绕由航点定义的"拐角"的最大速率,实际的转弯半径也受代理的速度和最大加速度影响。
Stopping distance: 制动距离:制动距离。到目的地的距离小于这个值,代理减速。代理很少能精确的着陆在目标点,所以这个属性可以用于设置一个可接受的范围内,代理应该停止。较大的停止距离会给代理更多回旋余地在路径的末尾,还可能避免突然刹车,转弯或不真实的人工智能行为。
Auto Traverse Off Mesh Link: 自动遍历OffMesh链接:自动移动并关闭OffMeshLinks,代理应该自动通过 OffMeshLinks 移动吗?Off-mesh链接是用于连接NavMesh不相交的区域。通常,如果这个属性设置为true,那么一个角色应该能够自动通过或者穿过链路。然而,在它被设为false的情况下,那么一个链路代表一扇门或者其他障碍,那么角色需要“许可”才能越过
Auto Braking:代理应该自动刹车避免过度到达目的地吗?如果代理需要移动的靠近目标点,那么它通常需要制动,以避免过度或没完没了的“绕着”目标区。如果这个属性被设置为true,代理将自动刹车,当它接近目的地的时候
设为true的情况 设为false的情况
Auto Repath: 自动重新寻路:如果现有的部分已失效,获得新的路径。代理应该尝试获得一种新的路径,如果现有的路径无效?
Height: 高度:代理的高度(用于调试图形)。就是设置的是“遮护罩”的高度,高度设置为和人物一样高就行了,就相当于设置对象的collider一样
Base offset: 基本偏移:碰撞几何体相对于实际几何体垂直的偏移。就是设置人物相对于“遮护罩”的垂直偏移
左边人物的Base offset设为-1,右边的设为2
程序运行后,两个人物的状态如下,可以看到,两个对象都发生了垂直方向的相对偏移了!左边的对象因为相对垂直偏移为-1,所以人物被挤到地形下面了,而右边的相对偏移为2,所以人物被挤上去了!
Obstacle Avoidance Type: 障碍躲避类型,躲避的质量水平。这是个枚举值,此属性允许你权衡躲避障碍的精度和对实现这一目标所需的处理器负载。精确的质量值将很大程度取决于场景的复杂性,但作为一般性规则,更快的性能将会以牺牲质量为代价,反之亦然。
Avoidance Priority:避开优先级,代理执行避开时,低优先级的代理人被忽略。有效的范围从0到99,最重要的= 0,最不重要= 99,默认= 50。
NavMesh Walkable: 导航网格行走:指定代理可以遍历的导航网格层类型。指定哪些NavMesh层可以通行。改变walkableMask将使路径失效
2、Off-mesh links组件
有时,场景中的静态几何体的导航网格不是全部相连在一起的(如上),从而使代理不能从世界场景的这一部分移动到另外的部分。
为了解决这个问题,Unity用了分离网格连接系统组件
Start:分离网格链接的开始点物体
End:分离网格链接的结束点物体
Cost Override:开销覆盖,如果值为正数,计算处理路径的请求时,路径开销。否则,我们使用默认开销成本(这个游戏对象所属的层的开销)。如果Cost Override的值设置为3.0,在分离网格的链接移动相同的距离的开销,是在默认的导航网的三倍。此属性是运行时可编辑,不需要重新烘焙。
Bi Directional:双向定向,如果勾上这个选项,链接的两个方向都可以通过,如果取消勾选的话,只能从开始点到结束点这样的链接方向通过。
Activated:激活,指定这个链接实际上是否由寻路者使用。当此属性为false,分离网格的链接将被不予理会。此属性是实时可编辑的,不需要重新烘焙。
Auto Update Position:自动更新位置,当他们的位置移动时,连接的端点可以自动更新吗
Navigation Layer:导航层,连接属于哪个导航层
分离网格链接OffMeshLink属性的特别注意事项
1、"Activated"和"Cost Override"的属性可以在运行时改变,有立竿见影的效果(值一改变,马上就产生效果)。其他所有属性改变需要重新烘焙导航网格才会起作用。
2、在烘焙时,如果未分配开始或结束的变换(transforms)的位置,或者是跟导航网格离得太远,而无法找到有效的位置,分离网格链接将不会产生。在这种情况下,在控制台窗口(Console window)中显示一个错误。
3、导航网格烘焙 navmesh baking
一旦导航网格几何体以及所属的层被标记好,该开始烘焙导航网格几何体
Radius:典型的代理的半径(值越小,效果越好)
Height:典型代理的高度(所需角色通过的高度)
Max Slope:最大坡度,大于这个斜坡的面,会被丢弃
Step Height:台阶的高度,高度差低于这,导航网格地区被视为连接。
Drop Height:下落高度,如果这个属性的值是正数,相邻的导航网格表面高度差低于此值,将进行网格连接。
Jump Height:跳跃距离,如果这个属性的值是正数,相邻导航网格表面的水平距离低于此值,将进行网格链接。
代理的半径(Agent Radius)控制着下降连接能达到多远,Drop Height控制着下降连接能有多长
Jump Distance(跳距离)控制 跳 - 过链接是如何计算出来的。注意,目的地必须在同一水平的开始。
min Region Area:最小区域面积,低于此临界值的区域将被丢弃。
Width Inaccuracy:宽度误差%,容许的宽度误差(百分比)
Height inaccuracy:高度误差%,容许的高度误差(百分比)
Height Mesh:高度网格,如果这个选项被选上,原始高度信息会存储起来。这对速度和内存性能有一定影响。
请注意,烘焙好的导航网格是场景的一部分,代理可以按照导航网格决定可否通过。要删除导航网格,在烘焙选项卡(Bake )点击清除(Clear )按钮。
看一张图,更容易理解:
Radius:半径,定义代理中心能够到达墙边或窗台的距离
Height:高度,定义代理能够到达多低的地方
Max Slope:最大坡度,定义代理走的坡度陡峭度
Step Height:台阶高度,定义代理可以踩多高的障碍物
4、导航网格障碍物 Navmesh Obstacle
在导航网格上的固定障碍物,可以作为烘焙过程中的一部分设置。但是,也可能在场景具有动态阻挡物,这将通过Agent移动来避开。这种动态障碍物,可以指定Navmesh Obstacle组件设置,可以被添加任何游戏物体上并随该对象移动。
Radius:障碍物圆柱的半径
Height:障碍物圆柱的高度
Move Threshold:移动阈值
Carve:切割
5、导航网格层
寻路系统的首要任务是找到寻路空间中2点的最优路径。在最简单的情况下,最优路径即最短路径。然而,在许多复杂的环境中,某些区域很难穿越(例如,穿过一条河流比通过桥梁更加费事)。为了模拟这些情况,unity引入代价(cost)和最优路径(optimal path)概念,即最低代价路径。unity使用导航网格层(Navmesh Layers)来管理路径代价。标记为静态导航网格的所有几何体都属于导航网格层。
寻路过程将对可能的路径进行代价评估,而不是进行长度比较。处理方法是对路径长度根据导航网格层的代价进行缩放。请注意,所有代价都设置为1时,最优路径相当于最短路径。
为一个用户层(user layer),设置名称和代价值。
名称用来在场景中标识导航网格层。代价值表示在导航网格层上移动的难易程度。默认为1(表示正常速度移动), 2表示2倍难度(表示2倍的难度移动),0.5表示为默认难度的一半。
有3个内置的层:
Default(默认)-所有没有做特殊设置的物体的默认代价值。
NotWalkable(不可穿越)-代价值忽略
Jump(跳跃)-自动生成的分离网格的代价
将自定义的层应用到指定几何体的步骤:编辑器中选择几何体 → 调出导航网格窗口(Window->Navigation Mesh) → 到Object标签,为物体选择你要设置的寻路层。
如果你在导航网格窗口启用了Show NavMesh选项,在编辑器中,不同的导航网格层会显示为不同的颜色。
如果你想让代理组件设置哪个层不能穿越:打开几何体的导航网格代理NavMesh Agent组件 → 更改NavMesh Walkable属性 → 不要忘记在脚本中设置代理的终点属性
注意:不建议把代价值设置为小于1的数值,因为这样的话寻路算法不能保证得到最优路径。