mcpField
N
navigation

navigation

github.com/drawcall-ai开发123 次安装
代码仓库

关于 navigation

navigation 是使用 navcat 生成导航网格并查询 3D 环境路径的技能。它指导游戏开发者提取几何体、查询路径和处理群体移动,并说明静态网格限制及随版本变化的 API。

主要功能

  1. 01从几何体生成导航网格
  2. 02生成单区或分块网格
  3. 03查询路径和可行走点
  4. 04检查表面视线
  5. 05沿路径移动 Agent
  6. 06群体寻路与避让

适用场景

  1. 01让游戏角色绕过障碍物
  2. 02查找巡逻或漫游目的地
  3. 03协调成群移动的 Agent
  4. 04地形变化后重建导航

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/drawcall-ai/skills --skill navigation

安装后在 Claude Code 中输入/navigation确认已加载。

详细介绍

使用 navcat 进行导航

navcat 根据原始几何体构建导航网格(关卡中相互连通、可供行走的多边形),并在其上处理寻路查询。当你需要让某个对象在世界中智能移动时,就可以使用它——例如让敌人绕过障碍物、让 NPC 巡逻、命令单位前往某个位置,或让 Agent 避开墙壁和空隙。它与渲染无关;navcat/three 可将其适配到 Three.js。

你真的需要导航网格吗?对于“在开阔平坦的地面上直奔目标”这种情况,导航网格有些大材小用——直接转向目标即可。当 Agent 必须绕过障碍物、穿越不平坦或多层地形,或作为协同人群移动时,导航网格才有用。如果你的场景更简单,自行实现转向逻辑才是正确选择。

版本会变化——请查看已安装的类型

本指南会帮你选择合适的功能和方案;它不会固定具体签名,因为 navcat 的 API(导出名称、选项字段、返回值结构)会随版本变化。在调用之前,请查看已安装软件包的导出和类型(navcat、navcat/blocks、navcat/three),确认当前的名称和字段。请将以下代码视为结构示例,而非接口约定。

流程概览

  1. 提取几何体——使用 navcat/three 中的 getPositionsAndIndices(meshes),将可行走的 Three.js 网格(地面、地形、障碍物)转换为 positions/indices。
  2. 生成导航网格——单个区域(默认情况)调用一次 navcat/blocks 中的 generateSoloNavMesh(input, options);对于大型世界和局部重建,则使用 generateTiledNavMesh。
  3. 查询——在生成的导航网格上查询路径、最近的可行走点、随机点和视线。
  4. 移动 Agent——每帧自行沿路径移动,或者将多个 Agent 交给 crowd 模块处理。
import { findPath, DEFAULT_QUERY_FILTER } from 'navcat'
import { generateSoloNavMesh } from 'navcat/blocks'
import { getPositionsAndIndices, createNavMeshHelper } from 'navcat/three'

const [positions, indices] = getPositionsAndIndices([floor, ...obstacles])
const { navMesh } = generateSoloNavMesh({ positions, indices }, options) // see options below

scene.add(createNavMeshHelper(navMesh).object) // debug: see the walkable surface

const result = findPath(navMesh, start, end, halfExtents, DEFAULT_QUERY_FILTER)
const waypoints = result.path.map((p) => p.position) // [x,y,z][]

halfExtents 是用于将 start/end 吸附到网格上的搜索框;如果查询失败,说明你的点可能不在导航网格上——请扩大搜索框,或先通过最近多边形查询进行吸附。

调整生成参数

生成选项会根据 Agent 的尺寸确定导航网格,并在细节与速度之间进行权衡。你无需记住所有字段(请从已安装的 SoloNavMeshOptions 中查看);只需理解几个重要参数即可:

  • Agent 尺寸——可行走的半径(与墙壁保持的间距)、高度(排除低矮天花板)、攀爬高度(可跨越的最大台阶高度),以及最大可行走的坡度角。请根据角色设置这些参数。
  • 分辨率——单元格的宽度/高度(体素网格):越小越精细,但速度越慢。常见的起始设置是单元格宽度 ≈ Agent 半径 / 3。
  • 简化——区域、边缘和误差限制决定生成的多边形会有多方正或平滑。

如需自定义单个生成阶段(标记区域、注入区域),navcat 还提供了更底层、类似 recast 的步骤,一次性生成器正是基于这些步骤构建的。只有当生成器无法满足需求时,才使用这些步骤。

查询导航网格

所有查询都需要导航网格和查询过滤器(除非标记区域代价/标志,否则使用 DEFAULT_QUERY_FILTER)。可用于寻路的功能包括:

  • findPath — 返回两点之间的完整路径,以路点表示。沿表面生成无转角路径可使用 findSmoothPath。(对于缓存或动态移动,节点路径与直线路径这对功能可提供更精细的控制。)
  • 最近的可行走点 — 将世界位置吸附到网格上;这是判断“此处是否可达”和修复查询失败的基础。
  • 随机可行走点(任意位置,或中心点周围一定半径内)— 用于生成点、巡逻目的地和漫游目标。
  • 沿表面执行 raycast — 检查网格上两点之间的视线。注意无命中约定:射线畅通时,返回的命中参数是该软件包表示“无墙”的哨兵值(一个最大值,而非 1.0 或 0)——请在已安装的类型定义中确认,切勿想当然。
  • moveAlongSurface — 在保持于可行走区域内的同时,将位置朝目标滑动;无需完整重新寻路的简单控制方式。
  • 离网连接 — 跨越网格无法连接的间隙的显式链接(跳跃、梯子、传送)。

每帧沿路径移动

findPath 会返回路点;如何移动 Agent 是由你的循环负责的。朝当前路点移动,抵达后前进到下一个路点;目标改变或 Agent 偏离路径时,重新寻路:

let waypoints = result.path.map((p) => p.position)
let i = 0

function updateAgent(pos, speed, delta) {
  if (i >= waypoints.length) return // arrived
  const t = waypoints[i]
  const dx = t[0] - pos[0], dz = t[2] - pos[2]
  const dist = Math.hypot(dx, dz)
  if (dist < 0.2) { i++; return }
  pos[0] += (dx / dist) * speed * delta
  pos[2] += (dz / dist) * speed * delta
}

多个 Agent → crowd 模块

对于群体(敌人蜂拥而至、单位集体移动),请使用 navcat/blocks 中的 crowd API,而不是手动沿路径跟随——它会帮你处理分帧寻路、Agent 间避和墙壁避障,以及保持间距。避免让群体挤成重叠的一团:

  • 为每个 Agent 设置与其身体尺寸相符的半径,并让避障功能保持间距。不要每帧都手动将所有 Agent 的速度直接设为朝向同一个点——这会覆盖避障效果,让它们叠在一起。
  • 若要围攻目标,为每个 Agent 设置一个位于目标周围环形区域上的偏移量(根据索引/角度分散),让它们包围目标,而不是争抢中心位置。
  • 调整避障强度和最大加速度,让 Agent 能相互绕行,而不是抖动或互相穿透。

如有高级需求,可将 crowd 模块复制到项目中并进行修改。

限制 — 知道何时需要自行补足

  • 导航网格是静态的。 它反映的是生成时的几何形状。可行走几何发生变化时(例如门打开、地形变形),你必须重新生成——generateSoloNavMesh 会重建整个区域;分块导航网格则只重建受影响的区块。对于少量移动障碍物,在导航网格上叠加你自己的局部转向/避障逻辑,通常比不断重建更省资源。
  • 约定: navcat 遵循 OpenGL 约定(右手系、逆时针绕序)。如果你的数据不同,请在输入和输出时转换坐标。导入的外部导航网格必须让相邻多边形共享/索引相同的顶点。
  • 确保碰撞几何与导航网格都贴合同一形状的地形——不要在起伏的地面下方使用平坦地板(参见 world 技能),否则 Agent 会穿过可见的山丘寻路。
  • 导航网格是普通 JSON——将生成的导航网格序列化后保存,可在加载时跳过重新生成。

评论

支持 Markdown