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. 高级进阶考点

用于实现跳跃、爬**或传送。它能连接两块不连续的 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
  • Q: SetDestination 返回 False 是为什么?
    • A: 目标点可能不在 NavMesh 覆盖范围内。可以使用 NavMesh.SamplePosition 将目标点投影到最近的有效网格点上。
  • Q: 如何处理不同类型的地表(如泥地走得慢,草地走得快)?
    • A: 使用 Navigation Areas (区域成本)。为不同地表设置不同的 Cost,Agent 寻路算法(A*)会自动绕开成本高的路径。
posted @ 2026-04-16 12:15  Reed_Chill  阅读(193)  评论(0)    收藏  举报