Godot NavigationAgent3D 敌人寻路:路径、避障和行为状态的配合

讨论 Godot NavigationAgent3D 在敌人 AI 中的路径刷新、局部避障、状态机和性能控制。

Godot 的 NavigationAgent3D 可以让 3D 角色沿导航网格移动,提供下一个路径点、目标可达性和避障能力。很多项目第一次使用时,会把它当成完整 AI:设置 target_position,然后敌人就应该聪明地追玩家。实际使用中,敌人是否追击、何时刷新路径、卡住怎么办、攻击距离如何判断、多个敌人如何避免拥挤,都不是 NavigationAgent3D 单独解决的问题。

寻路只是 AI 的一层。敌人行为状态机决定目标和意图,NavigationAgent3D 负责给出路径建议,角色控制器负责移动,战斗系统负责攻击和命中。边界清楚后,问题会更容易定位。

flowchart TD
    A[AI 感知] --> B[行为状态机]
    B --> C{当前状态}
    C -->|巡逻| D[巡逻目标点]
    C -->|追击| E[玩家预测位置]
    C -->|撤退| F[安全点]
    D --> G[NavigationAgent3D]
    E --> G
    F --> G
    G --> H[下一个路径点]
    H --> I[角色控制器]
    I --> J[碰撞/移动结果]
    J --> B

路径刷新要有节奏

最常见的性能问题,是每个敌人每帧都把玩家位置设为 target。玩家稍微移动,所有 NavigationAgent 都重新计算路径,CPU 很快被拖垮。路径刷新应该有节奏:目标移动超过一定距离、固定间隔、状态切换、路径阻断时再刷新。

追击玩家时,可以使用预测位置,但不要过度精确。敌人不需要每 16 毫秒知道玩家新位置。普通敌人 0.2 到 0.5 秒刷新一次路径通常够用,精英敌人可以更频繁。距离越远,刷新频率越低。

大批敌人还要分帧刷新。AIManager 可以把寻路请求排队,每帧处理一部分。玩家看不到所有敌人同一帧更新路径,但能明显感受到卡顿。

行为状态决定目标

巡逻、追击、攻击、搜索、撤退、返回出生点,每个状态的导航目标不同。NavigationAgent 不应该自己判断状态。比如敌人进入攻击距离后,行为状态机切到 Attack,导航可以暂停或只做微调;玩家脱离视野后,状态切到 Search,目标变成最后看到的位置。

状态切换时要清理路径。追击切攻击时,不要继续沿旧路径往前挤;攻击切追击时,重新设置目标。死亡或眩晕时,NavigationAgent 应停止更新,角色控制器也停止接收移动意图。

这样调试时很清楚:敌人不动,是状态不允许移动,还是 NavigationAgent 没路径,还是控制器被碰撞卡住。

避障不是解决拥挤的全部

NavigationAgent3D 的避障可以帮助角色避免互相重叠,但大批敌人围玩家时,仍然需要队形和占位规则。否则敌人会在玩家周围挤成一团,路径点不断变化,看起来抖动。

一种做法是给攻击目标周围分配槽位。敌人追击的不是玩家中心,而是某个可用攻击槽位。近战敌人占外围,远程敌人占更远位置。槽位由战斗或 AI 管理器分配,NavigationAgent 只负责走到槽位。

局部避障参数也要调。半径太大,敌人互相推开走不到目标;半径太小,模型重叠。不同体型敌人使用不同 avoidance 设置。不要所有敌人复制同一个 Agent 参数。

卡住检测要看移动结果

寻路有路径,不代表角色真的能走到。动态门、物理碰撞、其他角色、台阶、导航网格漏洞都会让敌人卡住。角色控制器应反馈实际移动结果:速度是否接近零、碰撞 normal、距离目标是否长期不变。

AI 状态机根据卡住信息处理:重新请求路径,尝试小范围绕行,切换目标,传送回合法点,或放弃追击。不要让敌人在墙角永远跑步。

卡住检测要避免误判。攻击前停下、等待动画、被眩晕都不是卡住。只有状态要求移动且长时间没有进展,才算卡住。

导航网格和关卡制作配合

NavigationAgent3D 的效果很依赖导航网格。斜坡、楼梯、窄门、跳台、动态障碍都要在关卡制作阶段验证。导航区域过窄,敌人会排队;边缘太贴墙,角色模型会擦墙;缺连接,敌人会绕远或不可达。

关卡工具可以显示导航岛、不可达区域、门口宽度和常用路径。AI 问题很多时候不是脚本,而是导航数据。内容团队需要能看到这些数据。

调试可视化

AI 寻路必须可视化。测试包显示敌人当前状态、目标点、路径线、下一个路径点、避障半径、卡住计时。玩家反馈“怪物傻站着”时,打开调试一看就知道是没有路径、状态不追击,还是目标槽位被占。

还可以记录 AI 事件:看到玩家、丢失目标、刷新路径、进入攻击、卡住恢复。事件时间线能帮助复现偶发行为。

小结

Godot NavigationAgent3D 是路径工具,不是完整敌人 AI。行为状态机决定目标,路径刷新有节奏,避障配合槽位系统,角色控制器反馈卡住,关卡导航数据要可视化。把这些层拆清楚,敌人才会看起来聪明,而不是一群会计算路径但不会行动的节点。
我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

我会给 AI 测试场景放窄门、斜坡、动态门、多个敌人围攻和远程站位。每次改导航参数都跑这张场景,比在正式关卡里等怪物偶发卡住更有效。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页