[脚本库] Baz导航代理移动

BazNavAgentMovement

用于 GameObject 的路径寻找 AI 移动。基于 Godot 内置的 NavigationAgent2D,使敌人能够绕墙移动而不是撞墙。六种行为,一个节点,无需手动编写状态代码。

下载:
baz_nav_agent_movement.gd (68.4 KB)

功能说明

使用 NavigationAgent2D 为敌人规划前往目标的路径。

  • 巡逻 (Patrol) — 按循环或乒乓顺序在航点之间移动
  • 追逐 (Chase) — 向对象、组或命名节点规划路径
  • 逃跑 (Flee) — 使用探测方向远离威胁规划路径
  • 随机漫步 (Random Walk) — 围绕起始位置在半径范围内漫游
  • 设定方向 (Set Direction) — 以恒定角度移动,避开障碍物
  • 移动到点 (Move To Point) — 一次性前往坐标、对象、组或命名节点

通过任何可视化脚本状态的单次调用即可在游戏过程中切换行为。速度、加速度和减速度从实体的现有 MoveAndJumpSettings 中读取。

设置 GameObject 导航节点

  1. 打开敌人的 GameObject(或 Area2DGameObject)场景。添加一个子级 Node2D,并将 baz_nav_agent_movement.gd 附加到它上面。

  2. 在敌人根节点下,将 NavigationAgent2D 作为 BazNavAgentMovement 的兄弟节点添加。默认设置即可开始使用。

  3. 选择 BazNavAgentMovement 节点,并从检查器下拉菜单中选择一种 行为模式 (Behavior Mode)。检查器仅显示与所选模式相关的字段。将鼠标悬停在任何字段上可查看工具提示。

行为模式 功能
巡逻 (Patrol) 按循环或乒乓顺序循环航点列表
追逐 (Chase) 向最近的合法目标规划路径
逃跑 (Flee) 远离最近的威胁规划路径
随机漫步 (Random Walk) 在起始位置半径内选择随机目的地
设定方向 (Set Direction) 以恒定角度移动,避开障碍物
移动到点 (Move To Point) 一次性前往坐标、节点或组成员

在可视化脚本中使用 BazNavAgentMovement

在敌人的可视化脚本中,选择您的 AI 状态并添加一个 InvokeScript 操作:

  • 目标节点:BazNavAgentMovement
  • 目标方法:apply_movement
  • 调用时机:OnStateUpdate

这就是全部运行时接线。apply_movement() 在首次调用时自动初始化,并在每个物理帧运行所选行为。

设置 GameScene 的 NavigationRegion2D 和 NavigationPolygon

  1. 打开敌人所在的游戏场景。添加一个 NavigationRegion2D,为其分配 NavigationPolygon 资源,并绘制可通行区域。

  2. 将您希望视为碰撞体的任何 TileMapLayer 或 StaticBody2D 作为 NavigationRegion2D 的子节点,并在编辑器工具栏中按 Bake NavigationPolygon(烘焙导航网格)。如果没有烘焙的导航网格,敌人将无法移动。

  1. 如果您需要在角落周围增加路径的半径,可以在 NavigationPolygon 资源中调整 Radius 属性。您必须重新烘焙它!

方法 (Actions)

方法 调用时机
apply_movement() 在活动的 AI 状态的每个物理帧调用 (OnStateUpdate)。基本使用必需。
reset_movement() 停止移动,并在下一次 apply_movement() 调用时重新初始化。仅在需要显式重置时才需要,因为当不再调用 apply_movement() 时,移动会自动停止。
switch_to_patrol() 在巡逻状态的 OnStateEnter 时调用。从航点 0 重新开始航点循环。
switch_to_chase() 在追逐状态的 OnStateEnter 时调用。获取最近的合法目标。
switch_to_flee() 在逃跑状态的 OnStateEnter 时调用。获取最近的威胁。
switch_to_random_walk() 在漫游状态的 OnStateEnter 时调用。
switch_to_set_direction() 在固定方向状态的 OnStateEnter 时调用。
switch_to_move_to_point() 在一次性移动状态的 OnStateEnter 时调用。冻结从配置源获取的目的地。
return_to_start() 规划路径返回出生位置。
return_to_nearest_patrol() 规划路径到最近的航点,并从那里恢复巡逻。

条件 (Conditions)

用于可视化脚本转换条件槽 (ScriptConditionEvaluator):

方法 为真时
is_at_destination() 实体已到达其当前目标
is_moving() 实体具有非零速度
has_completed_patrol() 完整的循环或乒乓周期已结束
is_at_start() 实体已回到其出生位置(8 像素范围内)
is_returning() 正在进行 return_to_start 或 return_to_nearest_patrol 行程
is_patrol_paused() 巡逻处于活动状态,且实体正在某个航点停留
is_patrol_at_last_waypoint() 巡逻处于活动状态,且实体位于或正前往最后一个航点
is_chase_has_target() 追逐处于活动状态,且已锁定合法目标

提示

  • 先烘焙导航网格。 缺少或未烘焙的 NavigationRegion2D 是导致没有任何移动的最常见原因。使用编辑器中的调试 > 可见导航 (Debug > Visible Navigation) 确认网格位于您认为的位置。
  • 速度来自 MoveAndJumpSettings。 如果选择了加速度,它甚至会跟随。
  • Debug Enabled 会将初始化、目标更新、模式切换和到达事件打印到输出中。发布时请关闭它。
  • 游戏过程中切换模式不会重置速度。 加速/减速斜坡会在切换之间保留。如果您想要硬停止,请先调用 reset_movement()
  • 设定方向使用“胡萝卜在前方”的路径寻找。 它会在前方 128 像素处投射一个目标并规划路径,因此向右移动的敌人仍然会绕墙移动,而不会永久偏离。
  • 每个实体一个节点。 同一实体上的两个 BazNavAgentMovement 节点会在每一帧争夺速度控制权。
6 个赞

正需要这个,但是一直没能成功,能否给出完整的演示示例?非常感谢!

欢迎加入论坛,@xinyn

如果一切顺利,我本周会制作一个关于如何使用它视频教程。在那之前,你能分享一下哪里出了问题吗?也许我可以帮上忙?

我制作了一个视频,介绍如何使用该脚本并设置导航区域(位于本讨论串的最顶部)。希望它对你有帮助!

这个视频帮到了我!现在我的zombie也已经按设定的动起来了,非常感谢!如果后续再遇到什么问题,我会来反馈的,再次感谢!

1 个赞

我又遇到一个问题:僵尸现在可以按照我的设定移动巡逻或者追击了,但是在这些过程中僵尸只能朝着一个方向,不再按移动方向改变朝向了 :sweat_smile:

我做了许多尝试,还是没能解决这个问题…

我能想到的唯一原因如下:

  1. 动画未针对多个方向进行设置
  2. 您正在切换的状态未将“移动”设为朝向类型

如果您已尝试上述方法但仍无法解决问题,能否将您的项目打包成 ZIP 文件发送至 pgmmv-support@gotchagotcha.jp,以便我调查具体原因?

感谢回复,您上面提到的原因1、2我都确认没有问题,应该不是这两处设置的原因。

我注意到您的演示视频Navigation Agent Movement - Action Game Maker Godot中,也是遇到了同样的问题:僵尸会按设定移动,但是移动时朝向始终面向下方,而不是面向移动方向。

僵尸动画是我这边设置得比较随意。你可以看到待机动画只有一个方向(朝下),所以如果你在待机状态下使用该动画,角色只会朝下。


谢谢你Baz,我的问题解决了,感谢你的耐心帮助~

1 个赞