关于 ai-behavior-trees-utility-ai
面向游戏开发者的 NPC 决策系统实现指南,涵盖行为树、Utility AI 及混合方案,并提供运行时结构与评分方法。
主要功能
- 01行为树运行时设计
- 02Blackboard 与节点组合
- 03Utility 评分与响应曲线
- 04动作选择策略
- 05BT 与 Utility AI 混合模式
- 06Tick、状态与性能指导
适用场景
- 01构建可复用的 NPC 行为树运行时
- 02依据当前条件为目标或动作评分
- 03结合结构化行为与分级选择
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gamedev-skills/ awesome-gamedev-agent-skills --skill ai-behavior-trees-utility-ai安装后在 Claude Code 中输入/ai-behavior-trees-utility-ai确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/behavior-tree-core.mdbest-practices-and-pitfalls.mdpractical-examples.mdutility-ai-system.md详细介绍
行为树与效用 AI
两种互补的 NPC 决策结构化方式,以及如何将它们结合起来。**行为树(BT)**以树的形式表达结构化、优先级明确、可响应的逻辑,并在每个步骤中进行“tick”。效用 AI通过归一化曲线为各个动作评分,并选出最佳选项,以此回答“我现在有多想选择每个选项?”。结合使用 BT 组织结构,并在需要权衡取舍时使用效用 AI,即可打造行为可信的 Agent。
此技能是 game-ai 的实现配套内容;game-ai 可帮助你在 FSM / BT / 转向 / 寻路之间做出选择。阅读 game-ai 来选择模型;阅读本文来构建运行时。
适用场景
- 用于构建可复用的 BT 运行时:包括
Blackboard、Node基类、动作 / 条件叶节点、Sequence/Selector/Parallel组合节点,以及装饰器(Inverter、Cooldown、Repeat)。 - 用于构建效用 AI决策器:包括响应曲线、考量因素,以及为动作评分并进行选择的评估器(可使用 max、softmax 或加权随机方式来增加多样性)。
- 用于构建混合 AI——BT 的叶节点将“选择哪种攻击 / 哪个目标”的决策委托给效用评估器。
**不适用场景:*若要在 FSM、BT、转向或寻路之间做出选择,以及实现 A / 导航网格寻路,请使用 game-ai。若要使用 Unreal 基于资源的 BehaviorTree/Blackboard、BTTask/BTService 和 AIController,请使用 unreal-behavior-trees。若要让导航网格 Agent 移动 NPC,请使用 unity-navmesh 或引擎的导航节点。
核心工作流
- 选择模型。 结构化、优先级明确、可中断的行为 → BT。持续进行“为每个选项评分”的决策(目标选择、需求、物品选择)→ 效用 AI。两者兼有 → 混合模式。
- 先设计 Blackboard。 每个 Agent 使用一个类型化键值存储作为共享内存,用于解耦节点;叶节点读取 / 写入其中的内容,彼此之间绝不持有引用。
- 编写叶节点。 条件会立即返回
Success/Failure;动作会跨帧返回Running,直到执行完毕。让叶节点保持精简,并明确其副作用。 - 组合节点。
Selector= OR / 回退(第一个非失败结果获胜);Sequence= AND(遇到第一个非成功结果时停止);Parallel用于并发分支。通过装饰器封装策略(取反、冷却、重复、强制成功)。 - 对于效用 AI:列出考量因素,将每个原始事实映射到归一化的 0..1 曲线,再进行组合(带补偿的加权乘积,或加权和),随后选择得分最高的选项——添加迟滞,避免 Agent 在得分相同时反复切换。
- 有意识地进行 tick。 每个决策步骤对树 / 评估器执行一次 tick(通常比渲染频率低)。在不同 tick 之间保留
Running状态;调试时在屏幕上绘制当前活动路径和每个动作的得分,以便验证和调整。
架构概览
行为树从上到下、从左到右进行评估;每个节点都会向父节点返回一个状态:
flowchart TD
Root["Selector (root)"] --> Combat["Sequence: Combat"]
Root --> Patrol["Action: Patrol"]
Combat --> See["Condition: CanSeePlayer?"]
Combat --> InRange{"Selector: Reach"}
Combat --> Attack["Action: Attack (Running)"]
InRange --> Close["Condition: InAttackRange?"]
InRange --> MoveTo["Action: MoveToPlayer (Running)"]
效用 AI 是一个评分流程——为每个候选动作评分后,再选出一个:
facts (distance, health, ammo…)
│ each fact → a normalized 0..1 response curve (consideration)
▼
score(action) = weight · combine(consideration_1 … consideration_n) # product+compensation or sum
▼
select: argmax · or softmax / weighted-random for variety · + hysteresis to avoid jitter
状态是所有节点共用的三值枚举——这是树具备可组合性的契约:
public enum Status { Success, Failure, Running }
public abstract class Node
{
public abstract Status Tick(Blackboard bb, float dt);
public virtual void Reset() { } // called when a parent abandons this subtree
}
// Selector = fallback/OR: return the first child that is not Failure.
public sealed class Selector : Composite
{
public override Status Tick(Blackboard bb, float dt)
{
for (; _current < Children.Count; _current++)
{
var s = Children[_current].Tick(bb, dt);
if (s != Status.Failure) return s; // Success or Running stops the scan
}
_current = 0;
return Status.Failure; // every child failed
}
}
与 Sequence 对应的 Selector(AND——遇到第一个非 Success 时停止)、Parallel、Blackboard、叶节点基类,以及所有装饰器,详见 references/behavior-tree-core.md。
一段代码了解效用评分
// A consideration maps one raw fact to 0..1 through a response curve.
float Score(Blackboard bb)
{
float distance01 = Curves.InverseLerp01(bb.Get<float>("distToPlayer"), 20f, 2f); // near = 1
float health01 = Curves.Sigmoid(bb.Get<float>("health01"), k: 8f, mid: 0.4f); // hurt = low
// Product + compensation keeps a single 0 from vetoing while low values still dampen.
return Curves.CompensatedProduct(new[] { distance01, health01 });
}
完整的曲线库(线性、二次、指数、逻辑 / sigmoid、smoothstep)、Consideration/UtilityAction 类型,以及 UtilityEvaluator 的选择策略,详见 references/utility-ai-system.md。
陷阱
- 每帧都从根节点重新勾选
Running状态的动作,会导致它重新启动。 返回Running并从上次中断处继续;只有在父节点确实放弃子树时,才调用Reset()。 - 每次 Tick 都重新评估整棵深层树会浪费时间并引发抖动。优先使用浅层树和条件中止(更高优先级的条件可以打断较低优先级的分支)。
- 考量因素未归一化。 如果一条曲线的输出范围是 0..100,另一条是 0..1,较大的值就会占据主导。每个考量因素都必须返回 0..1。
- 效用值接近时会抖动。 添加滞后机制:给当前正在运行的动作少量加分,让 Agent 坚持当前选择,而不是来回切换。
- 每个 Tick 都分配节点、闭包或数组会造成 GC 峰值。生成时构建一次行为树;确保每个 Tick 都不产生分配。
参考资料
references/behavior-tree-core.md— 黑板、Node/叶节点基类、动作与条件叶节点、Sequence/Selector/Parallel,以及装饰器库(完整 C# 代码)。references/utility-ai-system.md— 响应曲线库、Consideration、UtilityAction和UtilityEvaluator(argmax、softmax、加权随机、滞后机制)。references/practical-examples.md— 守卫从巡逻到战斗的行为树、基于村民需求的效用 AI,以及混合 Agent,可直接用作模板。references/best-practices-and-pitfalls.md— 内存管理、性能分析、避免深层树、事件驱动的中止,以及将效用 AI 与行为树结合(混合架构)。
相关技能
game-ai— 在有限状态机 / 行为树 / 转向之间进行选择;A* 和导航网格寻路。unreal-behavior-trees— Unreal 基于资源的行为树 / 黑板、任务、装饰器、服务。unity-navmesh— 执行“移动到”意图的NavMeshAgent。physics-tuning— 运动层的 Agent 半径、移动和碰撞响应。tower-defense、fps-shooter、rpg— 采用此决策层的游戏类型。