Unity基础 —— NavMesh 导航系统
目录
Unity NavMesh 导航系统详解
NavMesh(导航网格)是 Unity 提供的一套成熟的寻路解决方案,通过预计算(Bake)场景几何体生成可行走区域的数据结构,并配合寻路组件实现角色的自动化移动。
1. 核心工作流
A. 环境烘焙 (Baking)
- Static 标记: 必须将所有作为地面或障碍物的 GameObject 设置为 Navigation Static。
- Navigation 窗口:
- Agent Radius/Height: 定义角色能穿过的最小宽度和高度。
- Max Slope: 角色能爬上的最大坡度。
- Step Height: 角色能迈上的台阶高度。
- 结果: 烘焙后生成一个
.asset文件,存储了场景的拓扑信息(多边形网格)。
B. 导航代理 (NavMeshAgent)
挂载在需要移动的角色上,核心属性包括:
- Speed / Angular Speed: 移动与旋转速度。
- Stopping Distance: 离目标点多远时停止。
- Auto Braking: 靠近目标时是否自动减速(平滑停止)。
C. 动态障碍物 (NavMeshObstacle)
用于那些不需要烘焙但在运行时会阻挡路的对象(如可推开的箱子、开启的门)。
- Carve(雕刻): 勾选此项后,障碍物会在导航网格上即时“挖”出一个洞。
- 注意: 如果障碍物频繁移动,开启 Carve 会消耗 CPU 进行网格重新计算,建议仅在物体停止移动时开启。
2. 代码实现示例 (C#)
通过代码驱动 Agent 到达指定位置:
using UnityEngine;
using UnityEngine.AI; // 必须引用 AI 命名空间
[RequireComponent(typeof(NavMeshAgent))]
public class SimpleNavigator : MonoBehaviour
{
private NavMeshAgent _agent;
public Transform target;
void Start()
{
_agent = GetComponent<NavMeshAgent>();
}
void Update()
{
if (target != null)
{
// 每帧或定时更新目标点
_agent.SetDestination(target.position);
}
// 检查是否到达目的地
if (!_agent.pathPending && _agent.remainingDistance <= _agent.stoppingDistance)
{
Debug.Log("已到达目标点");
}
}
}
3. 高级进阶考点
A. Off-Mesh Link (非网格链接)
用于实现跳跃、爬**或传送。它能连接两块不连续的 NavMesh 区域。可以手动放置组件,也可以在烘焙设置中由系统根据距离自动生成(Drop Height / Jump Distance)。
B. NavMesh Surface (现代扩展)
Unity 官方提供的增强插件(NavMesh Components)。
- 优势: 支持在运行时生成 NavMesh,支持局部烘焙,支持预制体内部包含 NavMesh。
- 面试加分: 提到这个说明你关注 Unity 的现代化工作流,而非仅限于旧版固定窗口。
C. 与动画系统的同步
- 问题: 默认情况下 Agent 像“平移”一样移动,不符合物理逻辑。
- 方案: 使用
Root Motion。让动画驱动位移,而将agent.nextPosition同步给transform.position,或者关闭agent.updatePosition由脚本同步。
4. 常见问题排查
- Q: 为什么 Agent 经常穿模或卡住?
- A: 检查 Agent 的
Radius是否大于烘焙时的Agent Radius;检查障碍物是否开启了Carve。
- A: 检查 Agent 的
- Q: SetDestination 返回 False 是为什么?
- A: 目标点可能不在 NavMesh 覆盖范围内。可以使用
NavMesh.SamplePosition将目标点投影到最近的有效网格点上。
- A: 目标点可能不在 NavMesh 覆盖范围内。可以使用
- Q: 如何处理不同类型的地表(如泥地走得慢,草地走得快)?
- A: 使用 Navigation Areas (区域成本)。为不同地表设置不同的
Cost,Agent 寻路算法(A*)会自动绕开成本高的路径。
- A: 使用 Navigation Areas (区域成本)。为不同地表设置不同的

浙公网安备 33010602011771号