Files
zeling_v2/Docs/ThirdPart/BehaviorDesigner_Technical_Evaluation.md
2026-05-19 23:20:44 +08:00

68 KiB
Raw Blame History

Behavior Designer Pro v2.1.12 技术评估与使用手册

版本: Behavior Designer Pro 2.1.12
作者: Opsive
架构范式: ECS 调度引擎 + MonoBehaviour/DOTS 双模 Task 混合架构
Unity 要求: 2022.3+
依赖: com.opsive.shared 2.0.0、com.opsive.graphdesigner 2.0.0、com.unity.burst 1.8.17、com.unity.entities 1.3.8
许可: Unity Asset Store EULA
包路径: Packages/com.opsive.behaviordesigner/
官方文档: https://opsive.com/support/documentation/behavior-designer-pro/
命名空间: BehaviorDesigner.RuntimeBehaviorDesigner.Runtime.Tasks


目录

  1. 概述与设计哲学
  2. 架构总览
  3. 核心组件
  4. ECS/DOTS 集成架构
  5. System Group 执行层级
  6. 核心 ECS 系统
  7. Task 系统架构
  8. Composite 任务 (组合节点)
  9. Decorator 任务 (装饰节点)
  10. Action 任务 (行为节点)
  11. Conditional 任务 (条件节点)
  12. Event 系统 (事件节点)
  13. Conditional Abort 机制
  14. Subtree 系统
  15. SharedVariable 系统
  16. 序列化与持久化
  17. Editor 工具链
  18. 性能分析
  19. 与 BaseGames 架构集成方案
  20. 优缺点总结
  21. 总结与建议

1. 概述与设计哲学

1.1 什么是 Behavior Designer

Behavior Designer 是 Unity 生态中最成熟的行为树 (Behavior Tree) 插件之一。v2.x Pro 版本进行了重大架构升级:

核心特性:采用 ECS 作为内部调度引擎(树遍历、分支管理、条件中断均由 Burst 编译的 ECS System 驱动),同时提供 MonoBehaviour TaskECS Task 两种编程模型。自定义业务逻辑通常使用传统 MonoBehaviour TaskTask 基类),可直接访问 GameObjectTransform、协程等 Unity 原生 API而内置 Composite/Decorator 节点及高性能场景使用纯 ECS TaskECSTask<T,C> 基类),享受 Burst + Job 并行优化。两种 Task 可在同一棵行为树中混合使用。

行为树是 AI 决策的标准范式,通过树形结构组织:

  • Composite (组合) — 控制子节点执行顺序 (Sequence/Selector/Parallel)
  • Decorator (装饰) — 修饰子节点行为 (Inverter/Repeater/Cooldown)
  • Action (行为) — 执行具体操作 (移动/攻击/等待)
  • Conditional (条件) — 检查条件 (距离/Tag/碰撞)

1.2 v2.x vs v1.x 关键差异

维度 v1.x (经典) v2.x Pro (混合架构)
运行时核心 纯 MonoBehaviour 驱动 ECS World 调度 + MonoBehaviour/ECS 双模 Task
执行引擎 主线程递归遍历 ECS SystemGroup 调度 + Burst 编译 (Composite/Decorator)MonoBehaviour Task 仍由 TaskObjectSystem 在主线程执行
Task 数据 C# 对象 (GC) ECS Task → IBufferElementData (无 GC)MonoBehaviour Task → C# 对象 (堆分配)
并行能力 ECS Task 可 IJobEntity 多树并行MonoBehaviour Task 为主线程
可视化编辑 内置窗口 基于 GraphDesigner 新编辑器
Subtree ExternalBehaviorTree Subtree ScriptableObject (Subgraph 属性)
Variable SharedVariable SharedVariable + ECS 兼容
序列化 Unity 序列化 Opsive 自定义序列化
自定义 Task 继承 Task 基类 继承 Task (MonoBehaviour 模式) 或 ECSTask (DOTS 模式)

1.3 核心设计原则

原则 说明
数据驱动 行为树资产独立于代码,策划可通过编辑器配置
ECS 调度 + 双模 Task 核心树遍历由 ECS SystemGroup 驱动Burst 编译),业务逻辑支持 MonoBehaviour Task 和 ECS Task 两种编程模型
MonoBehaviour 友好 自定义 Task 继承 Task 基类即可访问 GameObject/Transform/协程等,无需 ECS 知识
可组合 Subtree 支持行为树模块化复用
可中断 Conditional Abort 实现实时条件重评估
可扩展 自定义 Task 只需继承 Action/Conditional 基类 + 覆写 OnUpdate()

2. 架构总览

2.1 整体架构图

┌──────────────────────────────────────────────────────┐
│                      Editor                           │
│  ┌──────────────────────────────────────────────────┐│
│  │ BehaviorMainWindow (GraphDesigner 编辑器)         ││
│  │  ├─ 可视化行为树编辑                              ││
│  │  ├─ 节点拖拽/连线/参数配置                        ││
│  │  └─ TransitionLibrary 编辑                       ││
│  └──────────────────────────────────────────────────┘│
│         Opsive.BehaviorDesigner.Editor.dll            │
└──────────────────────────────────────────────────────┘
                         │ 序列化
                         ▼
┌──────────────────────────────────────────────────────┐
│                     Runtime                           │
│  ┌────────────┐   ┌─────────────┐   ┌──────────────┐│
│  │ BehaviorTree│   │  Subtree    │   │BehaviorTree  ││
│  │ (MonoBehav) │   │ (SO Asset)  │   │   Data       ││
│  └──────┬─────┘   └──────┬──────┘   └──────┬───────┘│
│         │                │                   │        │
│         └────────────────┼───────────────────┘        │
│                          ▼                            │
│  ┌──────────────────────────────────────────────────┐│
│  │              ECS World                            ││
│  │  Entity + TaskComponent[] + BranchComponent[]     ││
│  │  + EvaluationComponent + Flag Components          ││
│  │                                                    ││
│  │  BehaviorTreeSystemGroup                           ││
│  │   ├─ BeforeTraversalSystemGroup                    ││
│  │   │    └─ ReevaluateSystem                         ││
│  │   ├─ InterruptSystemGroup                          ││
│  │   │    └─ ConditionalAbortsInvokerSystem           ││
│  │   └─ TraversalSystemGroup                          ││
│  │        ├─ EvaluationSystem                         ││
│  │        ├─ TraversalTaskSystemGroup                  ││
│  │        │    └─ [Task-specific Systems]              ││
│  │        └─ DetermineEvaluationSystem                ││
│  └──────────────────────────────────────────────────┘│
└──────────────────────────────────────────────────────┘

2.2 运行时目录结构

Packages/com.opsive.behaviordesigner/
├── Runtime/
│   ├── BehaviorTree.cs                  # MonoBehaviour 主控组件
│   ├── BehaviorTreeData.cs              # 序列化数据容器
│   ├── BehaviorTreeDataStructures.cs    # 辅助数据结构
│   ├── Subtree.cs                       # ScriptableObject 子树资产
│   ├── Components/
│   │   ├── BehaviorTreeComponents.cs    # ECS 组件 (TaskComponent, BranchComponent 等)
│   │   └── BakedBehaviorTree.cs         # ECS Baking 支持
│   ├── Groups/
│   │   ├── BehaviorTreeSystemGroup.cs   # 根系统组
│   │   ├── BeforeTraversalSystemGroup.cs
│   │   ├── TraversalSystemGroup.cs      # 遍历系统组(含循环逻辑)
│   │   └── TaskSystemGroup.cs
│   ├── Systems/
│   │   ├── TraversalSystems.cs          # EvaluationSystem, DetermineEvaluationSystem
│   │   ├── BeforeTraversalSystems.cs    # ReevaluateSystem, ConditionalAbortsInvokerSystem
│   │   ├── TaskObjectSystem.cs          # GameObject Task 执行系统
│   │   └── CleanupSystem.cs             # 清理系统
│   ├── Tasks/
│   │   ├── Task.cs                      # GameObject Task 基类
│   │   ├── ECSTask.cs                   # ECS Task 基类
│   │   ├── TaskStatus.cs                # 状态枚举
│   │   ├── TaskInterfaces.cs            # 接口定义
│   │   ├── ConditionalAbortType.cs      # 条件中断类型
│   │   ├── StackedTask.cs               # 堆叠任务
│   │   ├── TaskCoroutine.cs             # 协程封装
│   │   ├── TaskDelegateBase.cs          # 委托任务
│   │   ├── PlaceholderTasks.cs          # 占位符
│   │   ├── UnknownTasks.cs              # 未知任务处理
│   │   ├── ISubtreeReference.cs         # 子树引用接口
│   │   ├── Composites/ (9 类型)
│   │   │   ├── CompositeNode.cs         # 基类
│   │   │   ├── Sequence.cs              # 顺序: AND 逻辑
│   │   │   ├── Selector.cs              # 选择: OR 逻辑
│   │   │   ├── Parallel.cs              # 并行
│   │   │   ├── ParallelSelector.cs      # 并行选择
│   │   │   ├── PrioritySelector.cs      # 优先级选择
│   │   │   ├── RandomSelector.cs        # 随机选择
│   │   │   ├── RandomSequence.cs        # 随机顺序
│   │   │   └── UtilitySelector.cs       # 效用选择
│   │   ├── Decorators/ (15 类型)
│   │   │   ├── DecoratorNode.cs         # 基类
│   │   │   ├── Inverter.cs              # 取反
│   │   │   ├── Repeater.cs              # 重复执行
│   │   │   ├── Cooldown.cs              # 冷却
│   │   │   ├── Iterator.cs              # 迭代
│   │   │   ├── ReturnSuccess/Failure.cs # 强制返回状态
│   │   │   ├── UntilSuccess/Failure.cs  # 持续到目标状态
│   │   │   ├── ConditionalEvaluator.cs  # 条件评估
│   │   │   ├── PriorityEvaluator.cs     # 优先级评估
│   │   │   ├── PriorityVariableEvaluator.cs
│   │   │   ├── UtilityEvaluator.cs      # 效用评估
│   │   │   ├── UtilityCurveEvaluator.cs # 效用曲线
│   │   │   └── UtilityVariableEvaluator.cs
│   │   ├── Actions/ (40+ 类型)
│   │   │   ├── Action.cs / ActionNode.cs
│   │   │   ├── Wait.cs, Idle.cs, Log.cs, LogValue.cs
│   │   │   ├── SendEvent.cs, SetSubtree.cs
│   │   │   ├── SubtreeReference.cs, SubtreeReferenceSelector.cs
│   │   │   ├── ReturnStatus.cs, PerformInterruption.cs
│   │   │   ├── Start/Stop/RestartBehaviorTree.cs
│   │   │   ├── StackedAction.cs
│   │   │   ├── TargetBehaviorTree/GameObjectAction.cs
│   │   │   ├── Conversions/ (15+ 类型转换)
│   │   │   ├── IList/ (8 集合操作)
│   │   │   ├── Math/ (13 数学运算)
│   │   │   └── UnityObjects/ (3 Unity 对象操作)
│   │   ├── Conditionals/ (28+ 类型)
│   │   │   ├── Conditional.cs / ConditionalNode.cs
│   │   │   ├── HasReceivedEvent.cs, HasValue.cs
│   │   │   ├── IsBehaviorTreeActive.cs, RandomProbability.cs
│   │   │   ├── StackedConditional.cs
│   │   │   ├── Math/ (6 比较操作)
│   │   │   └── Physics/ (8 碰撞/触发检测)
│   │   ├── Events/ (11 类型)
│   │   │   ├── EventNode.cs, Start.cs
│   │   │   ├── OnReceivedEvent.cs, OnInterrupt.cs
│   │   │   └── OnCollision/Trigger Enter/Exit 2D/3D
│   │   └── Templates/
│   │       ├── ECSNodes.cs              # ECS Task 模板
│   │       └── GameObjectNodes.cs       # GameObject Task 模板
│   └── Utility/
│       ├── TraversalUtility.cs          # 树遍历工具
│       ├── ComponentUtility.cs          # 组件管理工具
│       ├── SaveManager.cs              # 存档管理
│       └── Types.cs                     # 类型工具
├── Editor/
│   ├── Opsive.BehaviorDesigner.Editor.dll  # 编辑器 (预编译 DLL)
│   ├── Managers/                           # 窗口/集成/欢迎屏幕
│   ├── NodeViews/                          # 节点 UI 渲染
│   ├── Icons/                              # 编辑器图标
│   └── Styles/                             # USS 样式
└── Samples~/                               # 示例场景和脚本

2.3 依赖关系图

com.opsive.behaviordesigner (本包)
  ├── com.opsive.shared (v2.0.0)
  │     ├── 序列化系统 (Serialization)
  │     ├── SharedVariable 系统
  │     └── 反射工具
  ├── com.opsive.graphdesigner (v2.0.0)
  │     ├── IGraph, IGraphComponent 接口
  │     ├── IEventNode, ILogicNode 接口
  │     └── 图编辑器框架
  ├── com.unity.entities (v1.3.8)
  │     ├── World, Entity, EntityManager
  │     ├── ISystem, IJobEntity
  │     └── IComponentData, IBufferElementData
  └── com.unity.burst (v1.8.17)
        └── [BurstCompile] 优化

3. 核心组件

3.1 BehaviorTree (MonoBehaviour)

主入口组件,挂载在 GameObject 上,管理行为树的生命周期:

public class BehaviorTree : MonoBehaviour, IGraph, IGraphComponent, ISharedVariableContainer
{
    // ─── 配置 ───
    string m_GraphName;                         // 行为树名称
    int m_Index;                                // 用户指定 ID
    BehaviorTreeData m_Data;                    // 序列化数据
    bool m_StartWhenEnabled;                    // 启用时自动开始
    bool m_PauseWhenDisabled;                   // 禁用时暂停而非停止

    // ─── 更新模式 ───
    UpdateMode m_UpdateMode;                    // EveryFrame | Manual
    EvaluationType m_EvaluationType;            // EntireTree | Count
    int m_MaxEvaluationCount;                   // Count 模式下每帧最大评估数

    // ─── ECS 关联 ───
    World m_World;                              // ECS World 引用
    Entity m_Entity;                            // 关联的 ECS Entity

    // ─── Subtree ───
    Subtree m_Subtree;                          // 可选的外部子树引用

    // ─── 静态注册表 ───
    static Dictionary<Entity, BehaviorTree> s_BehaviorTreeByEntity;
    static int BehaviorTreeCount;

    // ─── 生命周期方法 ───
    void StartBehavior(World, Entity, startBranchType);
    void StartBranch(World, Entity, eventTaskType);
    void InitializeTree(World, Entity);
    void InitializeBranch(World, Entity, eventTask);

    // ─── 序列化 ───
    void Serialize();
    void Deserialize(bool force);

    // ─── 查找 ───
    T FindTask<T>();                            // 找到第一个匹配类型的 Task
    void FindTasks<T>(T[] array);               // 找到所有匹配类型
    Task GetTask(int runtimeIndex);             // 按运行时索引获取

    // ─── 静态工具 ───
    static BehaviorTree GetBehaviorTree(Entity entity);

    // ─── 事件 ───
    Action OnBehaviorTreeStarted;
    Action<bool> OnBehaviorTreeStopped;
    Action OnBehaviorTreeDestroyed;

    // ─── 物理事件转发 ───
    Action<Collision> OnBehaviorTreeCollisionEnter;
    Action<Collision> OnBehaviorTreeCollisionExit;
    Action<Collision2D> OnBehaviorTreeCollisionEnter2D;
    Action<Collision2D> OnBehaviorTreeCollisionExit2D;
    Action<Collider> OnBehaviorTreeTriggerEnter;
    Action<Collider> OnBehaviorTreeTriggerExit;
    Action<Collider2D> OnBehaviorTreeTriggerEnter2D;
    Action<Collider2D> OnBehaviorTreeTriggerExit2D;
}

3.2 BehaviorTreeData — 序列化数据

public class BehaviorTreeData : ISerializable
{
    ITreeLogicNode[] m_Tasks;               // 逻辑节点数组
    IEventNode[] m_EventTasks;              // 事件节点数组
    SharedVariable[] m_SharedVariables;     // 共享变量
    ushort[] m_DisabledLogicNodes;          // 禁用的逻辑节点索引
    ushort[] m_DisabledEventNodes;          // 禁用的事件节点索引
    int m_UniqueID;                         // 唯一数据 ID
    int m_RuntimeUniqueID;                  // 运行时 ID

    // 变量名 → SharedVariable 映射
    Dictionary<VariableAssignment, SharedVariable> m_VariableByNameMap;

    // 节点管理
    void AddNode(ITreeLogicNode node);
    void RemoveNode(ITreeLogicNode node);
    void AddNode(IEventNode node);
    void RemoveNode(IEventNode node);

    // 序列化
    void Serialize();
    void Deserialize(...);
}

3.3 Subtree — ScriptableObject 子树

public class Subtree : ScriptableObject, IGraph, ISharedVariableContainer
{
    BehaviorTreeData Data;
    bool Pooled;                            // 是否池化复用

    void Serialize();
    void Deserialize(...);
    void DeserializeSharedVariables(bool force);
    void Clone(IGraph other);               // 深拷贝

    // 节点/事件管理
    void AddNode(ITreeLogicNode);
    void RemoveNode(ITreeLogicNode);
    ITreeLogicNode GetNode(Type type);
    IEventNode GetEventNode(Type type);

    // 变量
    T GetVariable<T>(string name);
    void SetVariableValue<T>(string name, T value);
}

3.4 UpdateMode & EvaluationType

public enum UpdateMode
{
    EveryFrame,      // 每帧自动评估
    Manual           // 手动调用 Tick()
}

public enum EvaluationType : byte
{
    EntireTree,      // 评估整棵树直到找到 Running 节点
    Count            // 每帧最多评估 N 个节点 (性能限制)
}

4. ECS/DOTS 集成架构

4.1 核心 ECS 组件

TaskComponent (每个 Task 节点的运行时数据)

public struct TaskComponent : IBufferElementData
{
    public ushort Index;                     // 树中的逻辑索引
    public ushort ParentIndex;               // 父节点索引
    public ushort SiblingIndex;              // 下一个兄弟节点索引
    public ushort BranchIndex;               // 所属分支索引
    public ComponentType FlagComponentType;  // 标记此 Task 活跃的 Flag 组件类型
    public bool Disabled;                    // 是否被禁用
    public TaskStatus Status;                // 当前执行状态
    public bool CanReevaluate;               // 是否参与条件重评估
    public bool Reevaluate;                  // 当前是否正在被重评估
}

BranchComponent (执行分支状态)

public struct BranchComponent : IBufferElementData
{
    public ushort ActiveIndex;               // 当前活跃 Task 索引
    public ushort NextIndex;                 // 下一个要执行的 Task
    public ushort LastActiveIndex;           // 上一个活跃 Task
    public ComponentType ActiveFlagComponentType;  // 当前活跃 Task 的 Flag
    public InterruptType InterruptType;      // 中断类型
    public ushort InterruptIndex;            // 触发中断的 Task 索引
    public bool CanExecute;                  // 本帧是否可执行
}

Flag 组件 (控制 Task 执行的标签组件)

每种 Task 类型有对应的 Flag 组件 (IComponentData, IEnableableComponent)

Flag 控制对象
EvaluateFlag 树是否需要评估
EnabledFlag 树是否启用
InterruptFlag 分支是否需要中断
InterruptedFlag 分支是否已被中断
SequenceFlag Sequence 节点活跃
SelectorFlag Selector 节点活跃
ParallelFlag Parallel 节点活跃
InverterFlag Inverter 节点活跃
TaskObjectFlag GameObject Task 活跃
... 其他 Task 类型各有独立 Flag

核心思想:通过 Flag 组件的启用/禁用控制哪些系统需要执行,避免不必要的系统调度。

EvaluationComponent (位掩码评估跟踪)

根据树中 Task 数量选择不同大小的变体:

变体 最大 Task 数 数据大小
EvaluationComponent32 < 192 32 字节
EvaluationComponent64 < 448 64 字节
EvaluationComponent128 < 960 128 字节
EvaluationComponent512 < 4,032 512 字节
EvaluationComponent4096 < 32,704 4,096 字节

每个 Task 在位掩码中占 1 bitFixedList*Bytes<ulong> 存储。

ReevaluateTaskComponent (条件中断数据)

public struct ReevaluateTaskComponent : IBufferElementData
{
    public ushort Index;                              // Task 索引
    public ConditionalAbortType AbortType;           // 中断类型
    public ComponentType ReevaluateFlagComponentType; // 重评估 Flag
    public ushort LowerPriorityLowerIndex;           // 低优先级范围下界
    public ushort LowerPriorityUpperIndex;           // 低优先级范围上界
    public ushort SelfPriorityUpperIndex;            // 自身优先级范围
    public ReevaluateStatus ReevaluateStatus;        // Active/Inactive/Dirty
    public TaskStatus OriginalStatus;                // 重评估前的原始状态
}

InterruptType

public enum InterruptType : byte
{
    None,                   // 无中断
    Branch,                 // 条件中断/效用触发
    ImmediateSuccess,       // 立即成功中断
    ImmediateFailure        // 立即失败中断
}

4.2 Baking 支持

public class BakedBehaviorTree : IComponentData
{
    public int StartEventConnectedIndex;
    public bool StartEvaluation;
    public string[] ReevaluateTaskSystems;      // 重评估系统类型名
    public string[] InterruptTaskSystems;       // 中断系统类型名
    public string[] TraversalTaskSystems;       // 遍历系统类型名
    public ulong[] TagStableTypeHashes;         // Flag 组件类型哈希
    public ulong[] ReevaluateFlagStableTypeHashes;
}

StartBakedBehaviorTreeSystem 负责将 Baked 数据还原为运行时组件。


5. System Group 执行层级

5.1 完整执行顺序

SimulationSystemGroup
└── BehaviorTreeSystemGroup (根)
    ├── BeforeTraversalSystemGroup (OrderFirst=true)
    │   ├── ReevaluateTaskSystemGroup
    │   │   └── [各 Task 类型的重评估系统]
    │   └── [其他预遍历系统]
    │
    ├── InterruptSystemGroup
    │   ├── ReevaluateSystem                     ← 标记需要重评估的 Task
    │   ├── ConditionalAbortsInvokerSystem        ← 比较重评估结果,触发中断
    │   ├── InterruptSystem                       ← 执行中断
    │   ├── InterruptedCleanupSystem (可选)       ← 清理中断标志
    │   └── InterruptTaskSystemGroup (UpdateAfter=InterruptSystem)
    │       └── [各 Task 类型的中断处理系统]
    │
    └── TraversalSystemGroup (UpdateAfter=InterruptSystemGroup)
        ├── EvaluationSystem                     ← Phase 1: 遍历树,激活/停用节点
        │
        ├── TraversalTaskSystemGroup              ← Phase 2: 执行活跃 Task
        │   ├── OnPreUpdate() callback
        │   ├── [各 Task 类型的执行系统]
        │   │   ├── SequenceTaskSystem (Burst)
        │   │   ├── SelectorTaskSystem (Burst)
        │   │   ├── ParallelTaskSystem (Burst)
        │   │   ├── InverterTaskSystem (Burst)
        │   │   ├── TaskObjectSystem              ← GameObject Task 执行
        │   │   └── ...
        │   └── OnPostUpdate() callback
        │
        ├── DetermineEvaluationSystem             ← Phase 3: 检查是否需要继续
        │
        └── EvaluationCleanupSystem (OrderLast=true) ← Phase 4: 重置标志

5.2 System Group 类说明

职责
BehaviorTreeSystemGroup 根组,位于 SimulationSystemGroup 内。无活跃行为树时自动禁用
BeforeTraversalSystemGroup 预处理条件重评估。OrderFirst=true 确保最先执行
TraversalSystemGroup 核心遍历循环:执行 Task → 评估 → 判断是否继续 → 循环
TraversalTaskSystemGroup 实际 Task 执行,提供 OnPreUpdate/OnPostUpdate 扩展点

遍历循环机制TraversalSystemGroup 实现内部循环 — 如果 DetermineEvaluationSystem.Evaluate == true(仍有 Running 叶子节点),则重复执行 EvaluationSystem + TraversalTaskSystemGroup + DetermineEvaluationSystem,直到所有分支稳定。


6. 核心 ECS 系统

6.1 EvaluationSystem

[BurstCompile]
public partial struct EvaluationJob : IJobEntity
{
    // 对每个分支:
    // 1. 检查活跃 Task 状态是否变为 Success/Failure → 回溯到父节点
    // 2. 如果 NextIndex != ActiveIndex → 切换活跃 Task
    //    - 禁用旧 Task 的 Flag 组件
    //    - 启用新 Task 的 Flag 组件
    //    - 设置 TaskComponent.Status = Queued
    // 3. 处理禁用节点 (跳过)
    // 4. 重置子节点状态
}

6.2 DetermineEvaluationSystem

// 检查是否有叶子 Task 处于 Running 状态
// 使用 5 种 EvaluationComponent 大小变体的 Job 并行查询
// 输出:
//   Active = true  → 树仍在运行
//   Evaluate = true → 需要继续评估循环

6.3 ReevaluateSystem

// 处理 Conditional Abort:
// 1. 遍历 ReevaluateTaskComponent 缓冲区
// 2. 检查 Task 是否满足重评估条件 (abort type + 范围)
// 3. 设置 ReevaluateStatus = Active
// 4. 启用重评估 Flag
// 5. 记录原始状态用于后续比较

6.4 ConditionalAbortsInvokerSystem

// 比较重评估后的 Task 状态与原始状态:
// 如果状态发生变化 → 触发 InterruptFlag → 设置 BranchComponent.InterruptType

6.5 TaskObjectSystem

// 执行 GameObject-based Task 的生命周期:
// 1. Queued → OnStart() → Running
// 2. Running → OnUpdate() → 返回 TaskStatus
// 3. Success/Failure → OnEnd()
//
// 对于 ITaskObjectParentNode:
//   使用 NextChildIndex 确定下一个子节点
//   父节点返回 Success/Failure 时中断所有子节点

6.6 EvaluationCleanupSystem

[BurstCompile]
// 每帧遍历结束后:
// - 启用 EvaluateFlag (若 EnabledFlag 启用)
// - 重置 BranchComponent.CanExecute = true
// - 重置 BranchComponent.LastActiveIndex = ushort.MaxValue

7. Task 系统架构

7.1 TaskStatus 枚举

public enum TaskStatus : byte
{
    Inactive,       // 未激活
    Queued,         // 已排队,下次 Update 开始执行
    Running,        // 正在执行
    Success,        // 执行成功
    Failure         // 执行失败
}

7.2 Task 基类 (GameObject-based)

public class Task
{
    // ─── 引用 ───
    GameObject m_GameObject;
    Transform m_Transform;
    BehaviorTree m_BehaviorTree;
    ushort m_RuntimeIndex;
    TaskStatus m_Status;

    // ─── 生命周期 ───
    virtual void Reset();                    // 重置 Task 值
    virtual void Initialize(BehaviorTree, int index);  // 初始化
    virtual void OnAwake();                  // 初始化后
    virtual void OnBehaviorTreeStarted();    // 行为树启动
    virtual TaskStatus OnStart();            // Task 开始 (Queued → Running)
    virtual TaskStatus OnUpdate();           // 每帧更新 (Running)
    virtual void OnEnd();                    // Task 结束 (Success/Failure)

    // ─── 物理回调 ───
    virtual bool ReceiveCollisionEnterCallback => false;
    virtual void OnCollisionEnter(Collision collision);
    // ... 2D 版本同理

    // ─── 协程支持 ───
    Coroutine StartCoroutine(string methodName);
    Coroutine StartCoroutine(IEnumerator routine);
    void StopCoroutine(string methodName);
    void StopAllCoroutines();
}

7.3 ECSTask<TSystem, TBufferElement> (ECS-based)

public abstract class ECSTask<TSystem, TBufferElement>
    where TSystem : ISystem
    where TBufferElement : unmanaged, IBufferElementData
{
    // 派生具体类型:
    // ECSActionTask<TSystem, TComponent>      : IAction
    // ECSCompositeTask<TSystem, TComponent>    : IComposite, IParentNode
    // ECSConditionalTask<TSystem, TComponent>  : IConditional
    // ECSDecoratorTask<TSystem, TComponent>    : IDecorator, IParentNode

    abstract ComponentType Flag { get; }
    abstract TBufferElement GetBufferElement();
}

7.4 双模式 Task 体系

模式 基类 数据存储 执行系统 性能 适用场景
GameObject Task Task / ActionNode C# 对象 (堆) TaskObjectSystem 一般 需访问 MonoBehaviour、自定义逻辑
ECS Task ECSTask<T,C> IBufferElementData (ECS) Burst 编译 ISystem 最优 纯数据逻辑、大量实体

7.5 Task 接口体系

// ─── 类型标记 ───
IAction                 // 行为节点
IComposite              // 组合节点
IConditional            // 条件节点 ([ReflectedType(typeof(bool))])
IDecorator              // 装饰节点
IConditionalReevaluation // 可重评估

// ─── 核心接口 ───
IAuthoringTask          // ECS 创作接口
  ComponentType Flag { get; }
  Type SystemType { get; }
  int AddBufferElement(World, Entity, GameObject);
  void ClearBufferElement(World, Entity);

IReevaluateResponder    // 条件重评估
  ComponentType ReevaluateFlag { get; }
  Type ReevaluateSystemType { get; }

IInterruptResponder     // 中断响应
  Type InterruptSystemType { get; }

// ─── 节点层级 ───
ITreeLogicNode          // 逻辑节点基接口
IParentNode             // 有子节点
IParallelNode           // 并行执行子节点
IContainerNode          // 堆叠容器
IEventNode              // 事件入口

// ─── Task Object ───
ITaskObjectParentNode   // GameObject 模式下的父节点
  ushort NextChildIndex { get; }

7.6 StackedTask

允许在单个节点中堆叠多个 Task类似行为栈

public class StackedTask
{
    Task[] m_Tasks;                          // 堆叠的 Task 数组
    ComparisonType m_ComparisonType;         // Sequence (AND) | Selector (OR)
    ushort m_ActiveIndex;                    // 当前活跃 Task 索引

    enum ComparisonType { Sequence, Selector }

    void Add(object taskOrMethod);
    void Remove(int index);
}

7.7 TaskCoroutine 协程支持

public class TaskCoroutine
{
    Coroutine Coroutine;
    void RunCoroutine();                     // 执行完整协程
    void Stop();                             // 停止协程

    delegate void TaskCoroutineEnded(TaskCoroutine, string name);
}

7.8 TaskDelegate 系统

支持方法代理到 Task 的绑定:

TaskDelegate                                 // 无参无返回
TaskDelegate<T1..T10>                        // 1-10 参数,无返回
TaskValueDelegate<TReturn>                   // 无参有返回
TaskValueDelegate<T1..T10, TReturn>          // 1-10 参数有返回

8. Composite 任务 (组合节点)

组合节点控制子节点的执行顺序和逻辑组合方式。

8.1 类型总览

类型 逻辑 子节点执行 典型用途
Sequence AND 从左到右,遇 Failure 即停 完整行动链 (检测→移动→攻击)
Selector OR 从左到右,遇 Success 即停 行为选择 (攻击 | 追击 | 巡逻)
Parallel 全部 同时执行,任一 Failure 则 Failure 边走边瞄准
ParallelSelector 全部 同时执行,任一 Success 则 Success 多种方式尝试
PrioritySelector 优先级 按优先值排序执行 动态优先级决策
UtilitySelector 效用 按效用分数选择 效用 AI
RandomSelector 随机 随机顺序执行选择 随机行为
RandomSequence 随机 随机顺序执行顺序 随机化巡逻

8.2 Sequence (顺序节点)

// ECS 实现:
public struct SequenceComponent : IBufferElementData
{
    public ushort Index;
    public ushort ActiveChildIndex;
}

// Burst 编译系统:
[BurstCompile]
public partial struct SequenceTaskSystem : ISystem { ... }

// 逻辑:
// 1. 子节点 Success → 执行下一个子节点
// 2. 子节点 Failure → Sequence 返回 Failure
// 3. 所有子节点 Success → Sequence 返回 Success
// 4. 支持 ConditionalAbort (IConditionalAbortParent)

8.3 Selector (选择节点)

// 逻辑:
// 1. 子节点 Success → Selector 返回 Success
// 2. 子节点 Failure → 执行下一个子节点
// 3. 所有子节点 Failure → Selector 返回 Failure
// 4. 支持 ConditionalAbort

8.4 Parallel (并行节点)

public struct ParallelComponent : IBufferElementData
{
    public ushort Index;
}

// 特殊机制:
// - 每个子节点获得独立的 BranchComponent (独立执行分支)
// - 初始化时添加中断组件
// - 任一子节点 Failure → 中断所有其他子节点 → Parallel Failure
// - 所有子节点 Success → Parallel Success

8.5 Composite 基类

public abstract class CompositeNode : Task, ITreeLogicNode, IParentNode,
    IComposite, ITaskObjectParentNode
{
    ushort Index { get; set; }
    ushort ParentIndex { get; set; }
    ushort SiblingIndex { get; set; }
    ushort RuntimeIndex { get; set; }
    virtual int MaxChildCount => int.MaxValue;
    virtual ushort NextChildIndex => (ushort)(RuntimeIndex + 1);
}

9. Decorator 任务 (装饰节点)

装饰节点包装单个子节点,修改其行为。

9.1 类型总览

类型 行为 典型用途
Inverter 取反子节点状态 (Success↔Failure) 否定条件
Repeater 重复执行子节点 N 次 多次攻击
Cooldown 冷却期间返回 Failure 技能冷却
Iterator 遍历列表执行子节点 遍历目标
ReturnSuccess 强制返回 Success 忽略失败
ReturnFailure 强制返回 Failure 强制中止
UntilSuccess 重复直到 Success 等待成功
UntilFailure 重复直到 Failure 等待失败
ConditionalEvaluator 条件满足才执行子节点 条件守卫
PriorityEvaluator 按优先级评估子节点 动态优先级
PriorityVariableEvaluator 变量驱动的优先级评估 变量优先级
UtilityEvaluator 按效用分数评估 效用 AI
UtilityCurveEvaluator 曲线驱动的效用评估 平滑效用
UtilityVariableEvaluator 变量驱动的效用评估 变量效用

9.2 Inverter (取反器)

public struct InverterComponent : IBufferElementData
{
    public ushort Index;
}

// Flag: InverterFlag
// System: InverterTaskSystem (Burst)
//
// 逻辑:
// - 子节点 Success → Inverter Failure
// - 子节点 Failure → Inverter Success
// - 子节点 Running → Inverter Running

9.3 Decorator 基类

public abstract class DecoratorNode : Task, ITreeLogicNode, IDecorator,
    IParentNode, ITaskObjectParentNode
{
    int MaxChildCount => 1;                  // 只允许一个子节点
    ushort NextChildIndex => (ushort)(RuntimeIndex + 1);
}

10. Action 任务 (行为节点)

行为节点是行为树的叶子节点,执行具体操作。

10.1 内置 Action 分类

流程控制

Task 功能
Wait 等待指定时长
Idle 空操作,立即返回 Success
Log 输出日志
LogValue 输出变量值
ReturnStatus 返回指定状态
PerformInterruption 手动触发中断

行为树控制

Task 功能
StartBehaviorTree 启动另一棵行为树
StopBehaviorTree 停止另一棵行为树
RestartBehaviorTree 重启行为树
TargetBehaviorTreeAction 作用于目标行为树
TargetGameObjectAction 作用于目标 GameObject

事件与子树

Task 功能
SendEvent 发送命名事件
SetSubtree 设置活跃子树
SubtreeReference 引用子树
SubtreeReferenceSelector 选择性引用子树

数学运算

Task 功能
BoolFlip 布尔取反
BoolOperator AND/OR/XOR
FloatOperator 加/减/乘/除 float
IntOperator 加/减/乘/除 int
RandomBool/Float/Integer 随机值
SetBool/Float/Int/String 设置变量
SetVector2/Vector3 设置向量

集合操作

Task 功能
AddGameObjectToArray/List 添加到集合
RemoveGameObjectFromArray/List 从集合移除
SelectGameObjectFromArray/List 按索引选择
RandomGameObjectFromArray/List 随机选择

类型转换

Task 功能
ConvertBoolToFloat/Int/String Bool 转换
ConvertFloatToInt/String/Bool Float 转换
ConvertIntToFloat/String Int 转换
ConvertStringToBool/Float/Int String 转换
ConvertGameObjectToTransform GO ↔ Transform

Unity 对象

Task 功能
SetEnabled 启用/禁用 GameObject
SetGameObject 设置 GameObject 变量
WaitForAnimatorState 等待 Animator 状态

10.2 自定义 Action 编写示例

[TaskCategory("MyGame")]
[TaskDescription("向目标移动")]
public class MoveToTarget : Action
{
    [SerializeField] private SharedGameObject _target;
    [SerializeField] private SharedFloat _speed;
    [SerializeField] private SharedFloat _stopDistance;

    public override void OnStart()
    {
        // 初始化
    }

    public override TaskStatus OnUpdate()
    {
        if (_target.Value == null) return TaskStatus.Failure;

        float dist = Vector2.Distance(
            transform.position, _target.Value.transform.position);

        if (dist <= _stopDistance.Value)
            return TaskStatus.Success;

        Vector2 dir = (_target.Value.transform.position - transform.position).normalized;
        transform.position += (Vector3)(dir * _speed.Value * Time.deltaTime);

        return TaskStatus.Running;
    }
}

11. Conditional 任务 (条件节点)

条件节点检查运行时条件,返回 Success (true) 或 Failure (false)。

11.1 内置条件分类

基础条件

Task 功能
HasReceivedEvent 是否收到指定事件
HasValue 变量是否有值
IsBehaviorTreeActive 行为树是否活跃
RandomProbability 随机概率检查
StackedConditional 堆叠多个条件

比较条件

Task 功能
BoolComparison 布尔比较
FloatComparison 浮点比较 (==, <, >, <=, >=, !=)
IntComparison 整数比较
Vector2Comparison 向量距离比较
Vector3Comparison 3D 向量距离比较
GameObjectComparison 对象引用比较

物理条件

Task 功能
HasEnteredCollision 是否发生 3D 碰撞进入
HasExitedCollision 是否发生 3D 碰撞退出
HasEnteredCollision2D 2D 碰撞进入
HasExitedCollision2D 2D 碰撞退出
HasEnteredTrigger 3D 触发器进入
HasExitedTrigger 3D 触发器退出
HasEnteredTrigger2D 2D 触发器进入
HasExitedTrigger2D 2D 触发器退出

11.2 条件重评估

条件节点实现 IConditionalReevaluation,支持 Conditional Abort 机制:

public abstract class ConditionalNode : Task, ITreeLogicNode,
    IConditional, IConditionalReevaluation
{
    // 默认 OnReevaluateUpdate() 调用 OnUpdate()
    virtual TaskStatus OnReevaluateUpdate() => OnUpdate();
}

12. Event 系统 (事件节点)

Event 节点是行为树的入口点,定义分支的触发条件。

12.1 EventNode 基类

public abstract class EventNode
{
    ushort ConnectedIndex;                   // 连接的第一个逻辑节点索引
    BehaviorTree BehaviorTree;               // 父树引用

    void Initialize(IGraph graph);
}

12.2 内置事件类型

Event 触发时机
Start 行为树启动时 (默认入口)
OnReceivedEvent 收到命名事件时
OnInterrupt 分支被中断时
OnCollisionEnter 3D 碰撞进入
OnCollisionExit 3D 碰撞退出
OnCollisionEnter2D 2D 碰撞进入
OnCollisionExit2D 2D 碰撞退出
OnTriggerEnter 3D 触发器进入
OnTriggerExit 3D 触发器退出
OnTriggerEnter2D 2D 触发器进入
OnTriggerExit2D 2D 触发器退出

12.3 多分支执行

每个 Event 节点创建一个独立的 Branch。多个 Event 可以同时触发,意味着行为树可以有多个并发执行分支

BehaviorTree
├── Start Event → Branch 0
│     └── Selector [主行为逻辑]
├── OnReceivedEvent("Alert") Event → Branch 1
│     └── Sequence [警报响应]
├── OnCollisionEnter2D Event → Branch 2
│     └── Sequence [碰撞处理]
└── OnInterrupt Event → Branch 3
      └── Sequence [中断恢复]

13. Conditional Abort 机制

Conditional Abort 是行为树中实现实时响应的核心机制。

13.1 ConditionalAbortType

public enum ConditionalAbortType : byte
{
    None,               // 不中断
    Self,               // 中断当前组合内的执行
    LowerPriority,      // 中断右侧低优先级兄弟
    Both                // Self + LowerPriority
}

13.2 中断范围图解

Selector (LowerPriority Abort)
├── Sequence [高优先级 - 战斗]
│   ├── IsEnemyVisible ← 条件 (ConditionalAbort = LowerPriority)
│   └── AttackEnemy
│
└── Sequence [低优先级 - 巡逻]       ← 可被中断
    ├── HasPatrolRoute
    └── Patrol

场景:
1. 初始无敌人 → IsEnemyVisible=Failure → 跳到 Patrol
2. 巡逻中IsEnemyVisible 被周期性重评估
3. 发现敌人 → IsEnemyVisible=Success → 中断 Patrol 分支
4. 切换到 AttackEnemy
Sequence (Self Abort)
├── IsHealthAbove50 ← 条件 (ConditionalAbort = Self)
└── AggressiveAttack

场景:
1. 初始血量 > 50% → 执行 AggressiveAttack
2. 受伤血量 < 50% → IsHealthAbove50 重评估=Failure
3. Self 中断 → 停止 AggressiveAttack → Sequence Failure

13.3 执行流程

1. BeforeTraversalSystemGroup:
   ReevaluateSystem:
     ├─ 遍历所有 ReevaluateTaskComponent
     ├─ 检查 AbortType 和范围
     ├─ 标记需要重评估的条件
     └─ 启用重评估 Flag

2. 各 Task 重评估系统执行:
   └─ 调用 task.OnReevaluateUpdate() 或 ECS 重评估 Job

3. InterruptSystemGroup:
   ConditionalAbortsInvokerSystem:
     ├─ 比较重评估结果与原始状态
     ├─ 如果变化 → 设置 InterruptFlag
     └─ 设置 InterruptType = Branch

   InterruptSystem:
     ├─ 在被中断的分支上调用 OnEnd()
     └─ 设置新的执行起点

13.4 Abort 范围计算

  • Self: 只能中断当前 Composite 的子节点范围 ([taskIndex, SelfPriorityUpperIndex])
  • LowerPriority: 中断右侧兄弟子树 ([LowerPriorityLowerIndex, LowerPriorityUpperIndex])
  • Both: 合并两者范围

14. Subtree 系统

14.1 概念

Subtree 允许将行为树的一部分存储为 ScriptableObject 资产,实现模块化复用

主行为树
├── Selector
│   ├── Sequence [Combat]
│   │   ├── IsEnemyNear
│   │   └── SubtreeReference → CombatSubtree.asset
│   └── Sequence [Patrol]
│       └── SubtreeReference → PatrolSubtree.asset

CombatSubtree.asset (独立文件):
├── Start Event
└── Selector
    ├── Sequence [近战]
    │   └── MeleeAttack
    └── Sequence [远程]
        └── RangedAttack

14.2 数据结构

// 子树注入数据
struct SubtreeAssignment
{
    int ReferenceIndex;              // SubtreeNodesReference 索引
    ushort NodeIndex;                // ISubtreeReference Task 索引
    int SubtreeIndex;                // 子树索引
    Subtree Subtree;                 // 实际子树引用
    ushort IndexOffset;              // 索引偏移 (多子树累加)
    ushort ParentIndex, SiblingIndex, NodeCount;
}

// 子树节点引用
struct SubtreeNodesReference
{
    ISubtreeReference SubtreeReference;   // 引用 Task
    ushort NodeIndex;                     // 节点索引
    ushort NodeCount;                     // 子树节点总数
    Subtree[] Subtrees;                   // 加载的子树
    ITreeLogicNode[][] Nodes;             // 反序列化的节点
}

14.3 关键 Action 节点

节点 功能
SubtreeReference 静态引用一棵子树
SubtreeReferenceSelector 动态选择引用哪棵子树
SetSubtree 运行时切换活跃子树

14.4 变量覆写

子树可以有自己的 SharedVariable注入主树时支持变量覆写 — 主树的变量值覆盖子树同名变量。


15. SharedVariable 系统

15.1 概念

SharedVariable 是行为树节点之间共享数据的机制。每个变量有名称和作用域。

15.2 作用域 (Sharing Scope)

作用域 可见范围 存储位置
Graph 当前行为树/子树 BehaviorTreeData
GameObject 同 GameObject 上所有 BT SharedVariableContainer
Scene 当前场景所有 BT SceneVariable
Global 全局所有 BT GlobalVariable

15.3 内置 SharedVariable 类型

类型 包装值
SharedBool bool
SharedFloat float
SharedInt int
SharedString string
SharedVector2 Vector2
SharedVector3 Vector3
SharedGameObject GameObject
SharedTransform Transform
SharedObject object (任意引用)

15.4 使用模式

// 在自定义 Task 中声明
public class MyTask : Action
{
    public SharedGameObject Target;       // Inspector 中可配置
    public SharedFloat Speed;

    public override TaskStatus OnUpdate()
    {
        // 读取
        var targetGO = Target.Value;
        float speed = Speed.Value;

        // 写入
        Speed.Value = 10f;

        return TaskStatus.Running;
    }
}
// 从外部代码设置
BehaviorTree bt = GetComponent<BehaviorTree>();
bt.SetVariableValue("Target", playerGameObject);
bt.SetVariableValue("Speed", 5f);

16. 序列化与持久化

16.1 序列化系统

Behavior Designer 使用 Opsive 自定义序列化系统(非 Unity 内置序列化):

BehaviorTreeData
  ├── m_TaskData: Serialization[]           // 逻辑节点序列化数据
  ├── m_EventTaskData: Serialization[]      // 事件节点序列化数据
  ├── m_SharedVariableData: Serialization[] // 变量序列化数据
  ├── m_DisabledEventNodesData: Serialization[]
  └── m_DisabledLogicNodesData: Serialization[]

16.2 序列化流程

编辑时:
  Editor → BehaviorTreeData.Serialize() → m_TaskData[], m_EventTaskData[]

运行时:
  BehaviorTree.Deserialize()
    → 从 m_TaskData[] 重建 ITreeLogicNode[]
    → 从 m_EventTaskData[] 重建 IEventNode[]
    → 从 m_SharedVariableData[] 重建 SharedVariable[]
    → 解析 Task 间引用 (TaskAssignment)
    → 解析变量引用 (VariableField → VariableAssignment)

16.3 SaveManager

public class SaveManager
{
    void Save();    // 保存所有实现 ISavableTask 的 Task 状态
    void Load();    // 恢复已保存状态
}

17. Editor 工具链

17.1 可视化编辑器

基于 com.opsive.graphdesigner 的图形编辑器,通过 Opsive.BehaviorDesigner.Editor.dll 提供:

核心窗口: BehaviorMainWindow — 节点拖拽、连线、参数配置。

功能 描述
节点编辑 可视化拖拽 Composite/Decorator/Action/Conditional 节点
连线 点击连接父子关系
参数面板 Inspector 中配置每个节点的 SharedVariable 和属性
运行时调试 运行时高亮活跃节点、显示 Task 状态
分组 将节点分组管理
注释 添加文本注释节点

17.2 NodeView 控件

控件 用途
EventNodeViewControl 事件节点渲染
TaskNodeViewControl 通用 Task 节点渲染
StackedTaskNodeViewControl 堆叠 Task 渲染
PriorityEvaluatorNodeViewControl 优先级评估 UI
UtilityEvaluatorNodeViewControl 效用评估 UI
WaitNodeViewControl Wait 节点特殊 UI

17.3 管理器

管理器 功能
AddOnsManager 附加组件管理
IntegrationsManager 第三方集成
SamplesManager 示例场景
Startup 编辑器初始化
WelcomeScreenManager 欢迎屏幕

17.4 USS 样式

TaskStyles.uss — Task 节点的统一样式定义。

17.5 Editor 为预编译 DLL

重要:编辑器核心代码以 Opsive.BehaviorDesigner.Editor.dll 形式提供,无法直接查看/修改源码。运行时代码为完整源码。


18. 性能分析

18.1 Burst 编译优化

所有核心系统使用 [BurstCompile] 标记:

系统 Burst 说明
EvaluationSystem 树遍历
DetermineEvaluationSystem 评估判断
EvaluationCleanupSystem 标志清理
SequenceTaskSystem 顺序节点
SelectorTaskSystem 选择节点
ParallelTaskSystem 并行节点
InverterTaskSystem 取反节点
ReevaluateSystem 重评估
TaskObjectSystem GameObject 模式 (需要 Managed 引用)

18.2 内存优化

优化 说明
位掩码评估 用 ulong 位掩码追踪 Task 评估状态,极致紧凑
大小自适应 根据 Task 数量选择 32~4096 字节变体
ushort 索引 用 2 字节索引代替完整引用
IBufferElementData ECS 数据存储,无 GC 压力
Subtree 池化 Subtree.Pooled 支持对象池复用

18.3 并行执行

Job System (多线程):
  ├── 多个 BehaviorTree Entity 可并行处理 (IJobEntity)
  ├── 位掩码操作天然线程安全
  └── 不同的 Task System 可以安排在不同线程

单帧内执行流:
  Frame N:
    [Thread 1] EvaluationJob for Entity A, B, C...
    [Thread 2] EvaluationJob for Entity D, E, F...
    [Main Thread] TaskObjectSystem (GameObject tasks)

18.4 扩展性限制

限制 说明
最大 Task 数 32,704 受 4096 字节 EvaluationComponent 限制
Parallel 子分支 无限制 每个子节点独立分支
层级深度 无限制 但深树影响遍历性能
变量作用域 4 级 Graph/GameObject/Scene/Global

18.5 性能建议

场景 建议
大量简单敌人 (100+) 使用 ECS Task 而非 GameObject Task
频繁条件检查 合理设置 ConditionalAbort避免每帧重评估不必要的条件
深度行为树 使用 EvaluationType.Count 限制每帧评估数
子树复用 启用 Subtree.Pooled 减少实例化
纯 ECS AI 使用 Baked 行为树,避免 MonoBehaviour 开销

19. 与 BaseGames 架构集成方案

19.1 项目定位

根据 BaseGames 架构文档(00_Architecture_Overview.md20_Enemy_AI.md

Behavior Designer 通过 Adapter 层包装,驱动所有敌人 AI 行为决策。

业务代码永远不直接调用 Behavior Designer API所有交互通过 IBehaviorAdapter 接口代理。

19.2 防腐层设计

┌───────────────────────────────────────────────┐
│  业务层 (Foundation / Entity)                   │
│    EnemyController, BossPhaseController        │
│    AbilitySystem, TagContainer                 │
│                                                │
│    通过接口交互,不引用 BehaviorDesigner 类型    │
│         │                                      │
│         ▼                                      │
│  ┌──────────────────────────────────┐          │
│  │ IBehaviorAdapter (接口)           │          │
│  │   Enable() / Disable()           │          │
│  │   SetVariable(name, value)       │          │
│  │   SendEvent(eventName)           │          │
│  └──────────┬───────────────────────┘          │
│             │                                  │
│  ┌──────────▼───────────────────────┐          │
│  │ BehaviorDesignerAdapter (Adapter) │          │
│  │   ├─ Enable → bt.EnableBehavior() │          │
│  │   ├─ Disable → bt.DisableBehavior()│          │
│  │   ├─ SetVariable → bt.SetVariable()│          │
│  │   └─ SendEvent → bt.SendEvent()   │          │
│  └──────────┬───────────────────────┘          │
│             │                                  │
│  ┌──────────▼───────────────────────┐          │
│  │ BehaviorTree (B.D. 原生组件)      │          │
│  │   ├─ 行为树遍历                   │          │
│  │   ├─ 自定义 Task 节点             │          │
│  │   └─ SharedVariable              │          │
│  └──────────────────────────────────┘          │
└───────────────────────────────────────────────┘

19.3 IBehaviorAdapter 接口

public interface IBehaviorAdapter
{
    void Enable();
    void Disable();
    void SetVariable(string name, object value);
    void SendEvent(string eventName);
}

19.4 BehaviorDesignerAdapter 实现

[RequireComponent(typeof(BehaviorTree))]
public sealed class BehaviorDesignerAdapter : MonoBehaviour, IBehaviorAdapter
{
    private BehaviorTree _bt;
    private void Awake() => _bt = GetComponent<BehaviorTree>();

    public void Enable() => _bt.StartBehavior();
    public void Disable() => _bt.StopBehavior();

    public void SetVariable(string name, object value)
    {
        switch (value)
        {
            case float f: _bt.SetVariableValue(name, f); break;
            case int i:   _bt.SetVariableValue(name, i); break;
            case bool b:  _bt.SetVariableValue(name, b); break;
            case GameObject go: _bt.SetVariableValue(name, go); break;
            case Vector3 v:    _bt.SetVariableValue(name, v); break;
        }
    }

    public void SendEvent(string eventName) => _bt.SendEvent(eventName);
}

19.5 EnemyController 集成

[RequireComponent(typeof(ActorCore))]
public sealed class EnemyController : MonoBehaviour, IDeathListener
{
    [SerializeField] private EnemyProfileSO _profile;

    private void Awake()
    {
        // 初始化行为树
        var bt = GetComponent<BehaviorTree>();
        if (bt != null && _profile.BehaviorTree != null)
        {
            // v2.x 使用 Subgraph 属性注入 Subtree SO
            bt.Subgraph = _profile.BehaviorTree;
            bt.SetVariableValue("DetectionRange", _profile.DetectionRange);
            bt.SetVariableValue("AttackRange", _profile.AttackRange);
            bt.SetVariableValue("PatrolSpeed", _profile.PatrolSpeed);
            bt.SetVariableValue("ChaseSpeed", _profile.ChaseSpeed);
        }
    }

    public void OnOwnerDeath()
    {
        var bt = GetComponent<BehaviorTree>();
        bt?.StopBehavior();
    }
}

19.6 自定义 BT Task 节点

BaseGames 定义了 [TaskCategory("BaseGames")] 的自定义节点,桥接架构内部系统:

Task 名 类型 功能
ActivateAbilityTask Action 通过 AbilitySystem 激活技能
CheckTagTask Conditional 检查 ActorCore.Tags 是否包含指定 Tag
GrantTagAction Action 向 ActorCore.Tags 添加 Tag
RemoveTagAction Action 从 ActorCore.Tags 移除 Tag
SetMovementModeAction Action 切换 IPhysicsBody 重力模式
NavigateToTargetTask Action 通过 INavigationAdapter 寻路
MoveToTargetTask Action 通过 IPhysicsBody 直线移动
IsWithinRange Conditional 自定义距离检查

19.7 EnemyStateHandler — Tag 驱动状态切换

BT 不直接操作组件开关,而是通过 GameTag + EnemyStateHandler 间接控制:

BT Task: GrantTagAction(State.Dormant)
  → TagContainer.Add(State.Dormant)
    → EnemyStateHandler 收到 TagAddedEvent
      → 禁用 Hitbox, 导航, 行为树...(根据 StateBinding 配置)

BT Task: RemoveTagAction(State.Dormant)
  → TagContainer.Remove(State.Dormant)
    → EnemyStateHandler 收到 TagRemovedEvent
      → 恢复 Hitbox, 导航, 行为树...

19.8 BossPhaseController — 行为树阶段切换

// Boss 根据血量阈值切换不同的 Subtree:
private void TransitionToPhase(int phaseIndex)
{
    _bt.StopBehavior();
    _bt.Subgraph = _phases[phaseIndex].PhaseBehaviorTree;  // v2.x Subtree SO
    _bt.StartBehavior();
}

19.9 典型行为树结构 (敌人)

BT: SkeletonPatroller
├── Selector
│   ├── Sequence [追击]                          ← ConditionalAbort: LowerPriority
│   │   ├── IsWithinRange(DetectionRange)        ← 条件节点 (持续重评估)
│   │   ├── NavigateToTarget(Player)
│   │   └── Sequence [攻击]
│   │       ├── IsWithinRange(AttackRange)
│   │       └── ActivateAbility: SwordSlash
│   └── NavigatePatrol(PatrolPoints)             ← 低优先级 (可被中断)

19.10 敌人实体组件装配

[EnemyEntity]
├── ActorCore                         # 属性/技能/Hitbox/Hurtbox
├── EnemyController                   # 初始化和配置
├── EnemyStateHandler                 # Tag 驱动状态切换
├── BehaviorTree                      # Behavior Designer 原生组件
├── BehaviorDesignerAdapter           # IBehaviorAdapter 实现
├── NavAgent                          # PathBerserker2d 寻路
├── NavAgentAdapter                   # INavigationAdapter 实现
├── NavMovementBridge                 # 寻路 ↔ 物理桥接
├── NavAbilityGate                    # 能力 ↔ Link 桥接
├── RaycastBody2D                     # 物理移动
├── AnimancerComponent                # 动画
├── Hitbox (ContactHitbox)            # 接触伤害
└── Hurtbox                           # 受击判定

19.11 数据驱动配置流

EnemyProfileSO (ScriptableObject)
  ├── DisplayName, FactionTag
  ├── AttributeTemplate → AttributeSet 初始化
  ├── Abilities[] → AbilitySystem.GrantAbility()
  ├── BehaviorTree (Subtree SO) → BehaviorTree.Subgraph
  ├── DetectionRange, AttackRange → SharedVariable 注入
  ├── PatrolSpeed, ChaseSpeed → SharedVariable 注入
  ├── LootTable → 死亡掉落
  ├── HitCue, DeathCue → 反馈配置
  ├── InitialStateTags → 初始状态 (Dormant 等)
  ├── MovementMode → 移动模式 (Ground/Flying/CeilingHang)
  └── AbilityLinkMappings → 导航能力桥接

20. 优缺点总结

20.1 技术评分

维度 评分 (1-10) 说明
功能完整度 9 覆盖行为树全部标准功能 + Utility AI + Parallel + Subtree
API 设计 8 双模式 Task 灵活;自定义 Task 采用熟悉的 MonoBehaviour 模式,学习成本低
文档质量 7 官方文档完整,但未充分强调 MonoBehaviour Task 的主流地位
性能 9 Composite/Decorator 由 Burst + ECS 驱动核心遍历极高效MonoBehaviour Task 主线程执行,性能可接受
易用性 9 可视化编辑器直观,自定义 Task 只需继承 Action/Conditional + 覆写 OnUpdate与 v1.x 编程体验基本一致
可维护性 7 Editor 为预编译 DLL 不可修改Runtime 完整源码
与项目契合度 9 通过 Adapter 层完美集成Tag 驱动架构天然契合;无需 ECS 知识即可开发自定义 Task
综合 8.3 项目 AI 核心框架

20.2 核心优势

优势 说明
混合架构 (ECS 调度 + MonoBehaviour Task) ECS 作为调度引擎提供高性能树遍历,自定义 Task 仍用熟悉的 MonoBehaviour 模式编写
MonoBehaviour Task 为主流开发模式 内置 42+ 个任务中 80%+ 采用 MonoBehaviour Task示例代码全部采用此模式自定义业务 Task 无需 ECS 知识
Burst 编译核心遍历 Composite/Decorator 等树结构节点全部 ECS + Burst 编译,零 GC
位掩码评估 极低评估开销
Conditional Abort 实时响应环境变化,无需手动管理中断逻辑
Subtree 复用 行为模块化Boss 阶段切换简洁
SharedVariable 灵活的数据共享机制
可视化编辑器 策划可参与 AI 调试和配置
事件驱动分支 物理/自定义事件触发独立执行分支
运行时源码 可调试可扩展

20.3 风险与缓解

风险 缓解方案
DOTS 依赖 (com.unity.entities) Entities 是 Unity 官方组件,长期维护有保障
Editor 为 DLL Runtime 完整开源Editor 通过 API 扩展
第三方维护风险 Opsive 活跃维护 10+ 年Runtime 源码可自维护
ECS 学习曲线 使用 GameObject Task 模式可避免直接写 ECS
v1→v2 API 变化 v2 API 更现代Subtree 替代 ExternalBehaviorTree

20.4 与备选方案对比

特性 Behavior Designer v2 NodeCanvas GOAP (ReGoap) 自研 FSM
行为树 完整 完整
DOTS/ECS 调度 内部引擎 需自建
MonoBehaviour Task 主流模式 N/A N/A
Burst 编译 (Composite/Decorator) 需自建
可视化编辑
Utility AI 内置 需自建
Conditional Abort N/A 需自建
价格 $90 Pro $60 免费 免费
社区/维护 活跃 10+ 年 活跃 较小 N/A

21. 总结与建议

21.1 总体评价

Behavior Designer Pro v2.1.12 采用 ECS 作为内部调度引擎,同时提供 MonoBehaviour Task 和 ECS Task 双模式编程模型的混合架构行为树解决方案。对于 BaseGames 这一项目:

  1. AI 决策核心 — 所有敌人和 Boss 行为由行为树驱动
  2. 架构契合 — Adapter 层隔离完美符合 BaseGames 防腐层设计
  3. 开发友好 — 自定义 Task 采用熟悉的 MonoBehaviour 模式(继承 Action/Conditional + 覆写 OnUpdate()),无需 ECS 知识
  4. Tag 驱动 — BT TaskGrantTag/RemoveTag+ EnemyStateHandler 实现声明式状态管理
  5. 数据驱动 — EnemyProfileSO + SharedVariable 注入,策划零代码配置敌人行为
  6. Boss 阶段化 — BossPhaseController 通过切换 Subtree SO 实现多阶段 AI

21.2 最佳实践

实践 建议
Task 模式选择 自定义业务 Task如 ActivateAbility、CheckTag使用 MonoBehaviour Task继承 Action/Conditional);仅极端性能场景考虑 ECS Task
Conditional Abort 检测条件 (如 IsEnemyInRange) 放在高优先级 Sequence 首位 + LowerPriority
行为树深度 控制在 5-8 层以内,过深用 Subtree 拆分
SharedVariable 命名 统一命名约定:DetectionRangeTargetAttackRange
自定义 Task 统一 [TaskCategory("BaseGames")] 标签分类
Adapter 业务层只通过 IBehaviorAdapter 交互
Tag 驱动 优先用 GrantTag/RemoveTag 间接控制,而非直接操作组件
Boss 设计 每个阶段独立行为树文件,通过 BossPhaseController 切换
事件通信 使用 SendEvent/OnReceivedEvent 替代轮询
性能 大量小怪考虑 EvaluationType.Count 限制帧评估量

21.3 关键文件速查

用途 文件 路径 (相对 Runtime/)
主入口 BehaviorTree BehaviorTree.cs
数据容器 BehaviorTreeData BehaviorTreeData.cs
子树资产 Subtree Subtree.cs
ECS 组件 TaskComponent / BranchComponent Components/BehaviorTreeComponents.cs
Baking BakedBehaviorTree Components/BakedBehaviorTree.cs
Task 基类 Task Tasks/Task.cs
ECS Task 基类 ECSTask<T,C> Tasks/ECSTask.cs
TaskStatus TaskStatus Tasks/TaskStatus.cs
条件中断 ConditionalAbortType Tasks/ConditionalAbortType.cs
接口 全部 Task 接口 Tasks/TaskInterfaces.cs
Sequence Sequence Tasks/Composites/Sequence.cs
Selector Selector Tasks/Composites/Selector.cs
Parallel Parallel Tasks/Composites/Parallel.cs
Inverter Inverter Tasks/Decorators/Inverter.cs
Repeater Repeater Tasks/Decorators/Repeater.cs
Cooldown Cooldown Tasks/Decorators/Cooldown.cs
Wait Wait Tasks/Actions/Wait.cs
SendEvent SendEvent Tasks/Actions/SendEvent.cs
SubtreeReference SubtreeReference Tasks/Actions/SubtreeReference.cs
Start Event Start Tasks/Events/Start.cs
OnReceivedEvent OnReceivedEvent Tasks/Events/OnReceivedEvent.cs
遍历系统 EvaluationSystem Systems/TraversalSystems.cs
重评估系统 ReevaluateSystem Systems/BeforeTraversalSystems.cs
GO Task 执行 TaskObjectSystem Systems/TaskObjectSystem.cs
清理系统 CleanupSystem Systems/CleanupSystem.cs
根系统组 BehaviorTreeSystemGroup Groups/BehaviorTreeSystemGroup.cs
遍历系统组 TraversalSystemGroup Groups/TraversalSystemGroup.cs
遍历工具 TraversalUtility Utility/TraversalUtility.cs
组件工具 ComponentUtility Utility/ComponentUtility.cs
保存管理 SaveManager Utility/SaveManager.cs
ECS 模板 ECSNodes Tasks/Templates/ECSNodes.cs
GO 模板 GameObjectNodes Tasks/Templates/GameObjectNodes.cs

文档版本: 1.0
基于: Behavior Designer Pro v2.1.12 源码分析 + 官方文档 + BaseGames 架构文档
架构参考: Docs/Architecture/00_Architecture_Overview.mdDocs/Architecture/20_Enemy_AI.md