寻路模块 private

寻路模块

本篇是可执行速查表。完整的客户端资源链路、Agent 生命周期、路径时长和远端预测见 20 客户端寻路与移动表现;Battle 接收移动包但不重跑 Unity NavMesh 的真实边界见 21 服务端寻路权威与移动同步。

目标与边界

所有移动、传送、刷怪和掉落点都必须先通过 NavMesh 校验,禁止直接把随机坐标写入 Transform。

核心文件:Assets/Code/Game/OLogic/Common/NavMeshTool.cs、Assets/Code/Game/OLogic/Random/RandomTool.cs、Assets/Code/Game/Server/Move/MoveControllerHelper.cs。

组件关系

静态碰撞体/NavMeshSurface
          -> NavMeshAgent
          -> NavMeshTool (SamplePosition/Raycast/CalculatePath)
          -> RandomTool (战斗落点/传送/掉落)

可复用代码

public static bool IsOnNavMesh(NavMeshAgent agent, Vector3 pos,
    float height = 0.3f)
{
    NavMeshHit hit;
    return agent != null &&
        NavMesh.SamplePosition(pos, out hit, height, agent.areaMask);
}

public static bool IsWalkablePathComplete(Vector3 source,
    Vector3 target, int areaMask)
{
    var path = new NavMeshPath();
    NavMesh.CalculatePath(source, target, areaMask, path);
    return path.status == NavMeshPathStatus.PathComplete;
}

随机点先 SamplePosition,需要视线时再 NavMesh.Raycast:

float3 result = default;
if (!RandomTool.RandomPointOnNavMesh(center, minRange, maxRange,
    agent.areaMask, ref result)) return false;
agent.SetDestination((Vector3)result);

参数约束

  • areaMask 来自当前 Agent,不要默认 NavMesh.AllAreas。
  • SamplePosition 距离过大可能吸到另一层。
  • 找不到合法点时延迟重试或回退出生点。
  • 动态障碍物启停后检查 IsOnNavMesh,必要时重新 Warp。

调试步骤

  1. Scene 视图开启 Navigation/AI 可视化。
  2. 核对 Agent 的 radius/height/areaMask 与烘焙设置。
  3. 失败日志记录 source、target、areaMask、path.status。
  4. 对 OffMeshLink 和门两端分别做 CalculatePath。