接入 StateTree 与 Blackboard
Stack 决定当前哪一层 AI 有控制权,Queue 执行已经决定的任务计划;两者不能互换。本篇让一个 AIController 先运行 Unit 行为,再被 Squad/Command 覆盖并回退,同时验证一条正式 Queue Dispatch 的精确完成结果。
1. 配置层级与 Stack
在 Project Settings 的 StateTreeLayerHierarchy 按低到高配置 Default、Unit、Squad 等项目层。Command 是保留最高层,不应把它当作普通资产层手动竞争。将 UGAIS_StateTreeStackComponent 添加到 AIController,而非 Pawn。
为 Unit 层设置一个基础 StateTree。调用 SetLayerStateTree 后先检查 RequestedLayer:它表示策略已选择的目标;再等待 AppliedLayer:它表示该 StateTree 已实际安装。两者暂时不同是安全切换期间的正常状态,不要在 Requested 改变时就假设行为已经发生。
清除 Squad/Unit 高层后,Applied 应回落到下一个有效低层。若在同一层替换 StateTree,监听 OnActiveLayerStateTreeReplaced,而不是误把它当成层切换事件。
2. 接入命令 StateTree 与 Blackboard
使用 UGAIS_CommandExecutionDefinition_StateTree 的命令会请求 Stack 的 Command 路由。Stack 把已接受命令的 Definition、变体、目标、范围与自身 Pawn 写到项目配置的 Blackboard Key;StateTree 只消费这些已验证上下文并在终结时回报结果。
先保持 UGAIS_DeveloperSettings 默认 Blackboard Key。若项目改名,必须同时更新 Settings、Blackboard 资产和所有读取它的 StateTree;只改其中一侧会出现“命令在 Command 层但 Tree 读不到数据”。
3. Queue:只为已决定计划使用 Dispatch
Queue 组件也放在 AIController。Dispatch 会替换当前计划并返回正式 Dispatch Handle;等待完成时必须保存并追踪这个精确 Handle。Enqueue 在已有 Dispatch 时扩展该计划并延后其完成;没有 Dispatch 时只是匿名工作,不提供可等待的完成合同。
例如“移动到掩体 → 等待 → 投掷 Ability”可作为一个 Dispatch。需要临时追加收尾动画时 Enqueue;需要另一个完整计划替换它时重新 Dispatch。不要用 Queue 判断哪个 AI 层优先,优先级仍由 Stack 拥有。
验证
检查 | 期望结果 |
|---|---|
Unit → Squad 覆盖 | Requested 先变化,Applied 完成安全切换后变化。 |
Command 开始/结束 | Command 层路由安装,结束后精确撤销并回退。 |
Dispatch 完成 | 只为保存的 Handle 读取结果/原因,旧 Handle 不能结算新计划。 |
Queue 被层切换清理 | 这是保护,不是 Queue 决定层级。 |
调试临时状态时可加入 Task: Debug Overlay Text,并打开 gais.DebugOverlay.Enable 与 gais.DebugOverlay.StateTree,把当前状态文本画在 Pawn 上方。它只用于本地诊断,不参与 StateTree 完成判定;详情见 StateTree Debug Overlay。
详细职责见 StateTree 调度系统,字段见 StateTree 队列与调度参数。
