Unity 3D 导航系统

过去,游戏开发者必须自己打造寻路系统,特别是在基于节点的寻路系统中,必须手动地在 AI 使用的点之间进行导航,因此基于节点系统的寻路非常烦琐。

Unity 3D 不仅具有导航功能,还使用了导航网格(navigation meshes),这比手动放置节点更有效率而且更流畅。

更重要的是,还可以一键重新计算整个导航网格,彻底摆脱了手动修改导航节点的复杂方法。

1) 设置 NavMesh

NavMesh 的设置方法很简单,在 Hierarchy 视图中选中场景中除了目标和主角以外的游戏对象,在 Inspector 视图中单击 Static 下拉列表,在其中勾选 Navigation Static 即可,如下图所示。

unity导航路线绘制 unity 导航_3d

2) 烘焙

执行菜单 Window→Navation 命令,打开导航窗口,单击右下角的 Bake(烘焙)按钮即可,烘焙后的场景如下图所示。 

unity导航路线绘制 unity 导航_3d_02

 接下来详细看看 Navigation 面板,它有 Object、Bake、Areas 这 3 个标签页。

其中,Object 标签页如下图所示,该标签页可以设置游戏对象的参数,如下表所示。当选取游戏对象后,可以在此标签页中设置导航相关参数。 

unity导航路线绘制 unity 导航_3d_03

参 数

功 能

Navigation Static

勾选后表示该对象参与导航网格的烘焙

Generate OffMeshLinks

勾选后可在导航网格中跳跃(Jump)和下落(Drop)

Navigation Area

导航区域

Bake 标签页如下图所示,是 Navigation 面板最重要的标签页,在该标签页下可以设置导航代理相关参数以及烘焙相关参数,参数说明如下表所示。 

unity导航路线绘制 unity 导航_3d_04

参 数

功 能

Agent Radius

设置具有代表性的物体半径,半径越小,生成的网格面积越大

Agent Height

设置具有代表性的物体的高度

Max Slope

设置斜坡的坡度

Step Height

设置台阶高度

Drop Height

设置允许最大的下落距离

Jump Distance

设置允许最大的跳跃距离

Manual Voxel Size

设置是否手动调整烘焙尺寸

Voxel Size

设置烘焙的单元尺寸,控制烘焙的精度

Min Region Area

设置最小区域

Height Mesh

设置当地形有落差时是否生成精确而不是近似的烘焙效果

3) 设置导航代理

导航代理(Navigation Agent)可以理解为去寻路的主体。

在导航网格生成之后,给游戏对象添加了一个 Nav Mesh Agent 组件,如下图所示。

Nav Mesh Agent 面板中各导航代理参数含义如下表所示。 

unity导航路线绘制 unity 导航_3d_05

属性分区

参 数

功 能

Agent Size

Radius

设置导航代理的半径

Height

设置导航代理的高度

Base Offset

设置圆柱体相对于本地坐标的偏移

Steering

Speed

设置最大移动速度

Angular Speed

设置最大角速度

Acceleration

设置最大加速度

Stopping Distance

设置离目标距离还有多远时停止

Auto Braking

激活时,到达目标位置前将减速

Obstacle Avoidance

Quality

设置躲避障碍物的质量,如果设置为0则不躲避其他导航 代理

Priority

设置自身的导航优先级,范围是0〜99,值越小,优先级 越大

Path Finding

Auto Traverse Off Mesh Link

设置是否采用默认方式经过链接路径

Auto Repath

设置当现有的路径变为无效时是否尝试获取一个新的路径

Area Mask

设置此导航代理可以行走哪些区域类型

实践案例:自动寻路

案例构思

使用 Unity 3D 开发游戏,自动寻路可以有很多种实现方式。A 星寻路是一种比较传统的人工智能算法,在游戏开发中比较常用。

另外,Unity 3D 官方内置的寻路插件 Navmesh 也可以实现自动寻路功能。

本案例旨在通过一个简单的三维场景漫游实现 Navmesh 自动寻路插件的使用。

案例设计

本案例在 Unity 3D 内创建一个简单的三维场景,场景内有各种障碍,通过 Navmesh 插件可以自动寻找到目标位置。

案例实施

步骤 1):新建三维场景,将其命名为 Navigation。其中,胶囊体作为动态移动的对象,球体作为导航的目标,如下图所示。 

unity导航路线绘制 unity 导航_unity_06

 步骤 2):选中场景中所有除了 sphere、cylinder 摄像机以及直线光以外的所有物体,单击 Inspector 面板中右上角的 Navigation Static,使这些物体成为静态物体,并设置成 Navigation Static 类型,如下图所示。 

步骤 3):执行菜单栏中的 Window→Navigation 命令,Navigation 面板如下图所示。

unity导航路线绘制 unity 导航_3D_07

步骤 4):单击该面板右下角的 Bake 按钮,即可生成导航网格,下图为已生成的导航网格。 

unity导航路线绘制 unity 导航_unity_08

步骤 5):下面就可以让一个胶囊体根据一个导航网格运动到目标 Sphere 位置。执行 Component→Navigation→Nav Mesh Agent 为该胶囊体挂载一个 Nav Mesh Agent,如下图所示。 

unity导航路线绘制 unity 导航_3d_09

步骤 6):最后写一个脚本就可以实现自动寻路了。创建 C# 脚本,将其命名为 DemoNavigation,脚本如下: 纯文本复制


步骤 7):脚本新建完成后挂载到胶囊体上,然后将 Sphere 赋予胶囊体的 Navigation 脚本,运行场景,如下图所示,胶囊体会运动到 Sphere 的位置。 

using UnityEngine;
using System.Collections;
public class DemoNavigation:MonoBehaviour{
public Transform target;
void Start(){
if(target!=null){
this.gameObject.GetComponent().destination=target.position;
}
}
}
————————————————

(Nav Mesh Obstacle) 一般来说,不可攀爬的 Nav Mesh 都被视为障碍物(Nav Mesh Obstacle),也可以直接将物体设为障碍物,即可以为游戏对象添加 Nav Mesh Obstacle 组件。

有别于普通的 Nav Mesh,Nav Mesh Obstacle 是一种不需要烘焙的障碍物,形状可以选择为立方体或胶囊体。

实践案例:障碍物绕行

案例构思

在自动寻路过程中,往往会遇到障碍物,在寻路过程中遇到障碍物要怎样解决呢?

Unity 官方内置的寻路插件 Navmesh 完美地解决了这个问题。

本案例通过一个简单的有障碍的场景,实现自动寻路中障碍物绕行功能。

案例设计

本案例在 Unity 3D 内创建一个有障碍的场景,场景内有一个 Cube 用来充当障碍物,通过 Navmesh 插件实现主角遇到障碍物时自动绕行效果。 案例实施 步骤 1):执行 File→Save Scene as 命令,将 Navigation 场景另存为 Obstacle 场景,如下图所示。 

unity导航路线绘制 unity 导航_游戏引擎_10

 步骤 2):执行 GameObject→3D Object→Cube 命令新建一个障碍物,将其放置在主角的前方,并赋予黑色材质,如下图所示。 

步骤 3):执行 Component→Navigation→Nav Mesh Obstacle 命令添加 Nav Mesh Obstacle 组件,如下图所示。 

unity导航路线绘制 unity 导航_unity_11

步骤 4):单击 Play 按钮进行测试,可以发现主角会绕过黑色立方体并到达终点,效果如下图所示。 

unity导航路线绘制 unity 导航_3D_12

unity导航路线绘制 unity 导航_3D_13