1. 原生导航系统
1. 基本使用
窗口->AI->导航 打开导航界面。
导航系统在使用前要先烘焙,拥有静态navigation static的对象会在上面根据要求生成可到达以及无法到达的区域,取消勾选该对象,以能够随意地在该对象上移动。
2. 烘焙导航网格
| 参数 | 描述 |
|---|---|
| 代理半径 | 区域与边缘的最小半径 |
| 代理高度 | 区域内地面与上方障碍物的最小高度 |
| 最大坡度 | 斜坡最大高度 |
| 步高 | 垂直台阶可上升的最大高度 |
3. 控制单位
为控制单位物体添加NavMeshAgent组件,并引入UnityEngine.AI。
| 面板功能 | 描述 |
|---|---|
| speed | 移速 |
| Angular Speed | 旋转速度 |
| Acceleration | 加速度 |
| Stopping Distance | 停止距离 |
| Auto Braking | 自动刹车 |
| 代码功能 | 描述 |
|---|---|
| SetDestination(Vector3) | 设置移动导航目标点 |
| updatePosition | 是否自动更新位置 |
| updateRotation | 是否自动更新旋转轴 |
| remainingDistance | 与目标的距离 |
| nextPosition | 导航网络的目标点 |
| desiredVelocity | 旋转的目标方向 |
代码实例:利用通过代码控制角色移动
private NavMeshAgent agent;
float rotateTime = 0;
public float rotateSmooothing = 7;
public float speed = 4;
void Start()
{
agent = GetComponent();
agent.updatePosition = false;
agent.updateRotation = false;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
agent.SetDestination(hit.point);
}
rotateTime = 0;
}
Move();
}
private void Move()
{
if(agent.remainingDistance > 0.5f)
{
agent.nextPosition = transform.position;
// agent.desiredVelocity 该朝向的方向
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(agent.desiredVelocity), rotateTime);
rotateTime = rotateSmooothing * Time.deltaTime;
// 前进方向永远与是自身的前方
// transform.Translate(transform.forward * speed * Time.deltaTime);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
4. 导航对象
| 选项 | 描述 |
|---|---|
| All | 显示所有 |
| Mesh Renderers | 显示导航网格渲染的对象们 |
| Terrains | 地形 |
5. navigation area(区域)
每种区域可以设置一个花费,给予对象一个经过这段路程的耗费值
若想对象完全无法到达,点击那个对象,在导航的对象中找到navigation area,设置为not walkable。
6. 平台跳跃
首先要在烘焙中设置跳跃高度。
为可以跳跃的平台设置Generate OffMeshLinks以生成可跳跃区域
7. 导航网络障碍
通过添加导航网络障碍,来为导航网络添加动态的障碍物
| 功能 | 描述 |
|---|---|
| 切割 | 在物体静止后重新生成导航网格(用于不经常移动的物体) |
8. Off Mesh Link
一个自定义的跳跃点,挂在在单独一个组件上
| 参数 | 描述 |
|---|---|
| 起始 | 起始位置 |
| 结束 | 结束位置 |
| 成本 | 等距耗费倍数 |
| 双向 | 是否双向 |
| 已激活 | 是否激活 |
| 自动更新位置 | 运行后是否根据两个坐标当时位置更新 |
9. NavMeshComponent
先要下载导入NavMeshComponents模块。
为导航面物体添加NavMeshSurface组件。
| 功能 | 描述 |
|---|---|
| Agent Type | 导航网格使用哪一类参数进行烘培(自定义后选择一种,与Nava Mesh Agent保持一致) |
| Collect Objects | 渲染范围(音量:指区域渲染) |
| Use Geometry | 渲染依据mush render还是碰撞器 |
| BuildNavMesh() | 重新烘培导航网络 |
2. 2D导航系统
1. 基本使用
- 基于原生导航系统的扩展
- 为需要导航的精灵添加组件 NavMeshModifier 设置导航区域
- 创建空对象,添加脚本 NavMeshSurface、NavMeshCollectSorces2D 组件。
点击 NavMeshCollectSorces2D 中的 Rotate Surface to XY 旋转至 XY 轴后,点击 NavMeshSurface中的烘焙,烘焙网络。
- 修改原生导航网络的代理,调整代理参数(如边界)。
- 为需要导航的对象添加脚本 Nav Mesh Agent
- 代码中使用
// 导航组件
NavMeshAgent agent;
// 目标
public Transform targetTrans;
void Start()
{
agent = GetComponent();
// 禁止旋转
agent.updateRotation = false;
agent.updateUpAxis = false;
}
void Update()
{
SetDestination(targetTrans.position);
}
// 插件存在小bug,如果在同一y轴时可能会无法正确寻路,因此需要手动为其添加位置偏移、
void SetDestination(Vector3 pos)
{
float agentOffset = 0.0001f;
Vector3 agentPos = (Vector3)(agentOffset * Random.insideUnitCircle) + pos;
agent.SetDestination(agentPos);
}
2. 设置不可走区域
-
为障碍物对象(瓦片地图)添加组件 NavMeshModifier。注意勾选重写覆盖为不可行走区域。
-
NavMeshModifierVolume 允许你设定区域障碍。
-
可在此处设置烘焙区域模型(形状)
3. 改用碰撞盒进行区域判定
- 原生设置是以图像精灵的纹理区域决定区域位置大小
- 根基碰撞盒的大小形状不同,可生成出不同形状的区域以及不可达区域。
- 修改此项即启用
