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<NavMeshAgent>();
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<NavMeshAgent>();
// 禁止旋转
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. 改用碰撞盒进行区域判定
- 原生设置是以图像精灵的纹理区域决定区域位置大小
- 根基碰撞盒的大小形状不同,可生成出不同形状的区域以及不可达区域。
- 修改此项即启用