今日速览
- Godot 寻路有三套方案:
AStar2D(自定义点图)、AstarGrid2D(网格地图)和NavigationServer2D(导航网格,适合自由移动的实时玩法),选错方案会事倍功半。 - 最小可用流程只需 3 步:加
NavigationRegion2D→ 画NavigationPolygon并 Bake → 角色下挂NavigationAgent2D写移动脚本。 - 核心 API 只有 4 个:
target_position(设目标)、get_next_path_position()(取下一个路径点)、is_navigation_finished()(判断到达)、外加两个距离参数调手感。 - 经典坑:第一帧地图还没同步,直接查路径会返回空;敌人”跳舞/来回踱步”通常是每帧都重算路径导致的。
- 避障(Avoidance)与寻路是两套独立系统:避障只负责”别撞到移动中的同类”,静态障碍物必须靠烘焙进导航网格解决。
核心学习内容
1. 先选对工具:三种寻路方案怎么挑
Godot 官方文档把 2D 寻路分成三类,对应不同游戏形态:
- AStar2D:自己定义”点 + 连线 + 权重”的图,适合只有固定几个关键位置的玩法(如棋盘、传送点)。
- AstarGrid2D:网格地图专用,不需要手动建点连线,给格子设通行/阻挡即可。地牢、俯视角网格类游戏首选,还能复用你的 TileMap 数据。
- NavigationServer2D(导航网格):用多边形面片(NavigationPolygon)定义”可站立区域”,角色可以到达区域内任意位置。横版动作、自由移动的 ARPG 首选,一大片空地只需一个多边形,大型地图性能更好,也是今天的主角。
2. 场景搭建:3 步让敌人学会绕路
以官方 “2D Navigation Polygon” 演示为蓝本:
- 场景根节点下加
NavigationRegion2D,选中后在检查器新建NavigationPolygon资源。 - 用工具栏的绘制工具圈出”敌人能走的区域”(围墙、坑洞不要圈进去),点击 Bake NavigationPolygon 烘焙。⚠️ 官方特别提醒:导航多边形边缘要离碰撞体留出余量,否则角色会卡在墙边反复蹭。
- 给敌人
CharacterBody2D加一个子节点NavigationAgent2D,挂脚本。
3. 追击脚本:4 个 API 组成的核心循环
extends CharacterBody2D
@export var movement_speed: float = 150.0
@onready var nav_agent: NavigationAgent2D = $NavigationAgent2D
func _ready():
# 距离参数要按角色速度和关卡尺度调
nav_agent.path_desired_distance = 4.0
nav_agent.target_desired_distance = 4.0
actor_setup.call_deferred()
func actor_setup():
# 关键:等一个物理帧,让 NavigationServer 完成地图同步
await get_tree().physics_frame
nav_agent.target_position = get_node("../Player").global_position
func _physics_process(_delta):
if nav_agent.is_navigation_finished():
return # 到达目标,别再查路径,否则原地抖动
var next_pos: Vector2 = nav_agent.get_next_path_position()
velocity = global_position.direction_to(next_pos) * movement_speed
move_and_slide()
要点拆解:
target_position一旦设置,寻路自动开始,路径由get_next_path_position()逐个吐出(导航系统不会替你移动角色,移动永远是你的代码负责)。path_desired_distance:离下一个路径点多近就切换到下一点;target_desired_distance:离终点多近算”到达”。角色速度快就把这两个值调大,否则会”跑过头又折返”。- 追击类敌人可以每 0.3~0.5 秒更新一次
target_position(用Timer或帧计数),既省性能又避免”被玩家甩开后原地抽搐”。
4. 进阶:多敌人避障与常见坑排查
多个敌人追同一个玩家会互相叠在一起,此时开启避障:勾选 NavigationAgent2D 的 avoidance_enabled,连接 velocity_computed 信号,在 _physics_process 里把期望速度喂给 set_velocity(),然后用信号回调里的 safe_velocity 移动。相关调参:radius(角色体型)、neighbor_distance(只避多近的邻居)、max_speed。
官方文档列了 4 个高频问题,值得背下来:
- 路径返回空 → 地图还没同步,用
call_deferred+await physics_frame解决(或检查NavigationServer2D.map_get_iteration_id()是否为 0)。 - 在两个点之间跳舞 → 每帧都在重算路径,检查是否把
target_position更新放进了_physics_process且无间隔。 - 偶尔折返/回头看一眼 → 跑太快超过了判定距离,调大两个 desired distance,或让导航多边形别太碎。
- 避障没生效 → 避障只对”同样开启避障的 agent”生效,且必须设置了
target_position才会输出 safe_velocity。
🎯 DeepSeek 提示词
提示词 1:生成完整的敌人追击 AI 脚本
适用场景:不想手写样板代码,直接让 DeepSeek 产出可用的追击敌人。
你是资深 Godot 4 游戏开发者。请为我的 2D 横版动作游戏写一个"近战敌人追击 AI"的 GDScript 脚本。
要求:
1. 节点结构:CharacterBody2D(敌人)下挂 NavigationAgent2D 子节点,另有一个 Area2D 作为近战攻击范围检测。
2. 行为:玩家进入 detection_range 后开始追击;距离小于 attack_range 时停止移动并攻击;玩家离开 detection_range 超过 3 秒后停止追击,回到巡逻点。
3. 追击用 NavigationAgent2D 寻路,记得处理"第一帧地图未同步"问题(用 call_deferred + await physics_frame)。
4. 目标位置每 0.4 秒刷新一次,避免每帧重算。
5. 导出变量:movement_speed、detection_range、attack_range、attack_cooldown,均可 @export。
6. 输出格式:先给完整脚本(带中文注释),再列 3 条"接入步骤"(场景里怎么搭节点、参数怎么设),最后列出 2 个最容易出错的点。
请直接给出代码,不要解释太多理论。
使用说明:跑出来的脚本如果报错,把报错原文粘回给 DeepSeek 让它修;接入时记得先有 Player 节点(脚本里引用了它的 global_position)。
提示词 2:寻路 Bug 诊断模板
适用场景:敌人表现诡异(抖动、折返、卡墙),把现象贴给 DeepSeek 做”医生”。
你是 Godot 4 寻路系统专家。我的敌人用 NavigationAgent2D 追击玩家时出现以下症状:
【症状】角色在两个相邻位置之间来回抖动,像在"跳舞",偶尔还会回头看向身后。
【我的配置】movement_speed=300(角色跑得很快);path_desired_distance=4.0;target_desired_distance=4.0;我在 _physics_process 里每帧都更新 nav_agent.target_position = player.global_position。
【完整脚本】(粘贴你的敌人脚本)
请按可能性从高到低列出原因,并针对每一条给出具体的修复代码。最后直接给我一份修改后的完整脚本。如果怀疑是配置问题而不是代码问题,请明确告诉我该改哪个属性的值、改成多少、为什么。
使用说明:这是个可复用的”症状→诊断→修复”模板。把【症状】【配置】【脚本】三段替换成你的实际情况即可,适合所有寻路异常(空路径、折返、避障失效都能套)。
提示词 3:网格地图换 AstarGrid2D 方案
适用场景:如果你的游戏是地牢/网格地图,别用 NavigationRegion2D,让 DeepSeek 直接改写。
你是 Godot 4 游戏开发者。我的地牢游戏用的是 TileMapLayer 搭的地图,现在要写"怪物从出生点寻路到玩家"的逻辑。
约束与要求:
1. 使用 AstarGrid2D(不要用 NavigationAgent2D/NavigationRegion2D),因为地图是格子的。
2. 基于已有 TileMapLayer 自动生成网格:遍历 tile 坐标,把"可行走格子"加入 AstarGrid2D(用 set_point_solid 或相应 API 标记阻挡格)。
3. 提供两个函数:update_navigation()(地图变化时重算)和 get_path(from_cell: Vector2i, to_cell: Vector2i) -> Array[Vector2i](返回路径格子序列)。
4. 怪物按路径移动时用 move_toward 平滑插值,不做瞬移;寻路失败(无路可达)时返回空数组并打印警告。
5. 输出:完整 GDScript(含中文注释)+ 一段示例调用代码(怪物 _physics_process 里怎么用)。
注意:请使用 Godot 4.x 的 AstarGrid2D API,不要用 Godot 3 的旧写法。
使用说明:地牢/棋盘类游戏用 AstarGrid2D 更省;拿到代码后重点核对 API 名(Godot 4 是 AstarGrid2D,别让 AI 写成 3.x 的 AStar2D 手动建点版本)。
学习心得
距离”用 DeepSeek 做出可上架 Steam 的游戏”又近了一步:敌人只会直线冲脸的游戏,玩家玩 10 分钟就会腻;会绕路、会包抄、会从侧门堵你的敌人,才撑得起”好玩”二字。今天这套 NavigationRegion2D + NavigationAgent2D 是 Godot 所有”会移动的 AI”(敌人、NPC、宠物)的地基,而且样板代码高度模板化——正是 DeepSeek 最擅长的场景:把今天的提示词 1 存好,以后每个新敌人类型(远程兵、BOSS)都能在 30 秒内生成一个可跑的追击脚本,再花时间只调”性格参数”(速度、索敌距离、攻击节奏),这才是 AI 辅助开发的正确姿势:AI 写骨架,人调灵魂。
明日关注
- 复习避障参数(radius / neighbor_distance / max_speed)与
velocity_computed信号回调的接线方式,做一个小场景实测多敌人追击 - 把今天 3 条提示词存进自己的”DeepSeek 提示词库”,补一条”让敌人沿路径做简单巡逻(走 A→B→A 折返)“的变体
- 对照自己的游戏原型:当前地图是自由移动还是网格制?据此确定该用 NavigationServer2D 还是 AstarGrid2D
本文由自动化学习流水线每日生成,坚持即学即记。
评论