mcpField
G
godot-ai-navigation

godot-ai-navigation

github.com/thedivergentai开发907180 次安装2 周前更新
代码仓库

关于 godot-ai-navigation

面向 Godot 开发者的 AI 导航技能,帮助根据代理数量、场景和导航变化选择合适的寻路方案。它强调目标重定向、可达性检查和受阻恢复,并将具体寻路脚本交由相关技能提供。

主要功能

  1. 01按代理规模选择节点或 RID
  2. 02动态烘焙与移动障碍策略
  3. 03配置导航层、链接和区域成本
  4. 04按计时器或距离重定向目标
  5. 05检查可达性并恢复受阻代理

适用场景

  1. 01为巡逻或追逐角色设置寻路策略
  2. 02处理程序生成关卡的导航网格变化
  3. 03为大量简单移动单位选择 RID 导航
  4. 04排查代理卡住或相互堆叠

安装

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

$npx skills add https://github.com/thedivergentai/game-dev-agentic-skills --skill godot-ai-navigation

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

附带文件references/ai-movement-recipes.mdreferences/migration-notes.md

详细介绍

决策树(必须读取的脚本触发条件)

1. Node Agent 还是 NavigationServer RID
信号选择寻路脚本(必须读取)
2D 俯视角/横版,Agent 少于约 50 个,可在编辑器中调整CharacterBody2D 上的 NavigationAgent2Dsmart_navigation_agent.gd
3D 地面/斜坡导航,Agent 少于约 50 个,由设计师放置区域CharacterBody3D 上的 NavigationAgent3D同一脚本(3D 分支);与 godot-physics-3d 配合处理刚体碰撞
数百至数千个简单移动体(2D 或 3D)NavigationServer 上的 RID Agentserver_navigation_setup.gd + low_level_avoidance.gd
Agent 卡住/抖动先进行卡住恢复,再频繁重新指定目标agent_stuck_detection.gd
2. 烘焙还是障碍物
信号选择寻路脚本(必须读取)
可行走几何发生变化(程序生成、门)异步解析 + 烘焙async_dynamic_baking.gd
移动平台/区域移动动态区域管理器dynamic_nav_manager.gd
弹丸/滚动危险物推动 AgentRVO 障碍物(无需完整重新烘焙)moving_obstacle_server.gd
优先选择道路而非泥地/水域区域进入/通行成本terrain_cost_manager.gd
3. 图层、链接、人群
信号选择寻路脚本(必须读取)
行走/飞行/游泳(或阵营)筛选导航图层位掩码layer_mask_navigation.gd
跳跃/传送/电梯边NavigationLink 遍历nav_link_traversal.gd
队形/避免人群拥挤相对于领队的偏移group_avoidance_formations.gd
热路径查询内存分配重用查询参数/结果对象memory_optimized_queries.gd

请勿加载 所选行以外的脚本(例如:单个由设计师调整的 Agent 跳过 RID/服务器脚本;只有 RVO 障碍物移动时跳过异步烘焙)。

4. Chase / patrol 重定向策略(AI 层)
  • 追逐:按计时器(约 0.2 秒)或距离阈值重定向——绝不每个物理帧都设置 target_position。
  • 巡逻:仅当 is_navigation_finished() 且 is_target_reachable() 时才前往下一个路径点;若无法到达,则选择下一个路径点或重新寻路。
  • 状态所有权:巡逻/追逐/搜索状态转换由 godot-state-machine-advanced 负责;此技能只负责在状态指定目的地后决定如何重定向。

**巡逻状态交接(调用位置):**在巡逻状态的 _physics_process 中,当 Agent 到达路径点时,调用 retarget_if_needed(next_waypoint)——不要直接从状态机根节点设置 target_position。

# PatrolState.gd — state machine owns transitions; this skill owns retarget policy
func _physics_process(_delta: float) -> void:
	if nav_agent.is_navigation_finished() and nav_agent.is_target_reachable():
		_ai_nav.retarget_if_needed(_waypoints[_index])
		_index = (_index + 1) % _waypoints.size()
# Threshold retarget — AI policy, not per-frame path spam
const RETARGET_DIST := 1.5
var _last_target: Vector3

func retarget_if_needed(desired: Vector3) -> void:
	if desired.distance_to(_last_target) < RETARGET_DIST:
		return
	nav_agent.target_position = desired
	_last_target = desired

AI 导航中绝对不要做的事

  • 绝不要在等待物理帧之前设置 target_position——必须先调用 call_deferred(),然后执行 await get_tree().physics_frame。
  • 绝不要在运行时同步烘焙——通过寻路脚本 async_dynamic_baking.gd 使用 bake_from_source_geometry_data_async。
  • 绝不要每帧轮询追逐目标——这会导致路径重新计算过于频繁。
  • 绝不要在此处自行编写重复的本地导航脚本——仅从 godot-navigation-pathfinding 实现。
  • 绝不要忽略 is_target_reachable() / 卡住恢复机制——无法到达目标或停滞的 Agent 需要相应策略(agent_stuck_detection.gd)。
  • 启用 avoidance_enabled 时,绝不要将避让半径设为 0——Agent 会彼此穿过。
  • 绝不要每帧调用 get_path()——复用路径查询对象(memory_optimized_queries.gd)。

后备方案(未安装 godot-navigation-pathfinding)

如果无法使用同级技能,请使用以下精简的卡住恢复检查清单——不要凭记忆粘贴完整的烘焙/RID 教程:

  1. 通过 call_deferred + await get_tree().physics_frame 延迟设置第一个 target_position。
  2. 按计时器(约 0.2 秒)或距离阈值重定向——绝不要每帧执行。
  3. 停滞时:若 !nav_agent.is_target_reachable() 或速度连续 N 帧约为 0,则跳过路径点或调用 get_next_path_position() 进行恢复。
  4. 避让:启用 avoidance_enabled 时,将 radius 设为大于 0。
  5. 发布异步烘焙或 RID 群集功能之前,重新安装 godot-navigation-pathfinding。

专家见解(原因——保留在正文中)

  • 延迟设置第一个目标——原因:NavigationAgent 的地图/区域在 _ready() 中尚未就绪。call_deferred + await physics_frame 可防止首次路径计算失败。
  • 重定向策略——原因:每帧设置 target_position 会重新烘焙路径并导致 CPU 占用激增。仅使用计时器(约 0.2 秒)或距离阈值。
  • 无法到达的路径点——原因:若没有 is_target_reachable() + 跳过/重新寻路策略,巡逻循环会永远停滞。
  • 避让半径为 0——原因:启用避让但半径为 0 时,分离效果会失效;Agent 会堆叠在一起。

推荐流程

  1. 根据上述决策树判断 AI 需求。
  2. 必须打开所选行对应的每个已链接寻路脚本——不要加载该技能的其他脚本。
  3. 在此处接入重定向/状态策略(计时器/阈值 + 状态机),通过 CharacterBody 移动。
  4. 除非需要首次设置区域烘焙 UI,否则不要加载官方文档中的入门示例(请使用参考链接)。

深入示例(按需查看)

主题参考资料 / 脚本
追逐 / 巡逻 / 群集 AI 示例ai-movement-recipes.md

参考

渐进式披露:只有在研究特定 API 时才打开官方文档链接;只有在需要切换到相关领域时才加载相关技能——不要预先加载整个技能网络。

官方文档
  • 导航概览 — 深入查看类页面之前,先浏览地图、区域、Agent、网格、连接、障碍物和性能的教程索引。
  • 导航简介(2D) — 最小化的 NavigationRegion2D + NavigationAgent2D 配置、可行走多边形的烘焙,以及首帧就绪状态。
  • 导航简介(3D) — 对应的 3D 初始化流程,使用 NavigationRegion3D / NavigationAgent3D,并介绍网格烘焙的预期行为。
  • 使用 NavigationAgents — target_position、get_next_path_position、避让半径,以及用于追逐/巡逻 AI 的 velocity_computed 安全速度流程。
  • 使用 NavigationServers — 为无节点群体和大规模自定义服务端配置使用 RID 地图/区域/Agent。
  • 使用导航网格 — 解析/烘焙源几何体、异步烘焙,以及用于动态挖空的投影障碍物。
  • 使用 NavigationRegions — 区域归属、进入/移动成本,以及用于地形惩罚的分块/运行时区域更新。
  • 使用 NavigationObstacles — RVO 推开障碍物与烘焙时挖空,无需每帧完整重建网格。
  • 使用 NavigationLinks — 跳跃/传送/电梯边,以及 Agent 上的手动连接遍历。
  • 使用导航层 — 用于行走/飞行/游泳(或阵营)路径筛选的 32 位层位掩码。
  • 使用导航路径查询对象 — 重用 NavigationPathQueryParameters/Result,避免群体中每帧产生 GC。
  • 优化导航性能 — 面向大型 AI 群体的烘焙成本、Agent/障碍物数量和服务端查询预算。
相关技能
前置条件
  • godot-navigation-pathfinding — 必须使用权威的 NavigationServer 脚本(异步烘焙、RID 配置、查询重用、卡住检测);此技能没有本地 scripts/。
  • godot-characterbody-2d — 路径拐点通过 move_and_slide 转换为 CharacterBody 速度;Agent 脚本假设父节点是一个物理体。
  • godot-2d-physics — 碰撞层/形状仍会阻挡物理体;导航网格不能替代墙壁和触发器的物理碰撞。
  • godot-physics-3d — 3D Agent 遵循相同的区分:NavigationServer 路径与 RigidBody/CharacterBody 碰撞和斜坡处理各自独立。
补充
  • godot-raycasting-queries — 视线、瞄准锥和命中预测与寻路相辅相成,适用于追逐/潜行 AI。
  • godot-state-machine-advanced — 巡逻/追逐/搜索状态决定何时重新指定 NavigationAgent 目标,以及何时停止。
  • godot-tilemap-mastery — TileMap/TileSet 几何数据通常会用于 2D 关卡中的 NavigationPolygon 烘焙。
  • godot-3d-world-building — 静态网格和 GridMap 通常是烘焙区域的 NavigationMesh 源几何数据。
  • godot-procedural-generation — 运行时布局生成后,需要执行 parse + bake_from_source_geometry_data_async。
  • godot-signal-architecture — AI 系统通过发出类型化信号而非轮询时,velocity_computed / navigation_finished 的连接会更加清晰。
下游/使用方
  • godot-genre-rts — 单位移动命令和 RVO 人群会直接使用 NavigationAgent/Server 模式。
  • godot-genre-tower-defense — 路线/路径上的敌人和动态障碍物依赖区域、代价和障碍物更新。
  • godot-genre-stealth — 守卫巡逻和调查点是受检测状态控制的 NavigationAgent 路线。
  • godot-combat-system — 接战/风筝/包抄移动会基于路径指定新目标,并处理卡住后的恢复。
  • godot-monte-carlo-balancer — 调整 AI 难度时,可模拟追逐可达性、行进时间范围和人群压力。
主模块
  • godot-master — 此领域技能的库路由器和镜像模块入口。

评论

支持 Markdown