总览
这组文章默认你从来没用过 StateTree。你不需要先懂 FStateTreeExecutionContext、FStateTreeDataHandle 这些源码名词;第一步只要知道:StateTree 是 Unreal 用来组织“一个对象当前处于什么状态、状态里做什么事、什么时候切到另一个状态”的工具。它比一堆 Blueprint Branch 清楚,比 Behavior Tree 更像分层状态机,也能和 AI、GameplayTasks、Mass 一起用。
我们用同一个守卫案例贯穿:守卫先站岗,过一会巡逻;看见玩家后警戒,确认后追击;玩家跑远后搜索;搜索失败返回岗位。你会先做出能跑的树,再逐步理解 State、Task、Condition、Transition、Evaluator、Global Task、Parameter、Schema、Context、External Data、Property Binding 和 Debugger。
这组文章怎么读
如果你是完全新手,按顺序读。不要先跳到源码篇。StateTree 最容易让人困惑的地方,是编辑器里所有东西都像“节点”,但它们职责完全不同:State 是状态,Task 是做事,Condition 是判断,Transition 是切换规则,Evaluator 是算数据,Schema 是告诉这棵树能访问哪些外部对象。
| 读者问题 | 应该先看 |
|---|---|
| 我完全不知道 StateTree 是什么 | 第一篇 |
| 我想马上让 NPC 跑起来 | 第二篇 |
| 我总分不清 Task 和 Condition | 第三篇 |
| 我不知道变量从哪里来 | 第四、五、六篇 |
| 我写 C++ Task 不知道生命周期 | 第七篇 |
| 我的树乱跳或不跳 | 第八、十二篇 |
| 我有旧 Behavior Tree | 第十篇 |
| 我想在 Mass 里用 | 第十一篇 |
专题分篇目录
- StateTree 到底是什么,先别急着写节点:先建立用途边界。
- 第一个守卫 StateTree,从创建资产到跑起来:一步一步让 NPC 动起来。
- State、Task、Condition、Transition 四件套:把编辑器面板看懂。
- Evaluator、Global Task、Parameters 和数据从哪里来:解释输入、输出和共享数据。
- Schema、Context 和 External Data:理解资产为什么要选 Schema。
- Property Binding 数据绑定,像接水管一样接变量:学会把来源属性接到目标属性。
- Task 生命周期,Enter、Tick、Exit 到底什么时候调用:写 C++ Task 前必看。
- Transition 选择、优先级和调试:排查跳转错误。
- GameplayStateTree、组件运行和 AI MoveTo:把树接到 Actor/AIController。
- StateTree 和 Behavior Tree 怎么配合:旧项目迁移路线。
- StateTree 和 Mass,批量 AI 里怎么用:理解 Mass StateTree。
- 调试、性能和生产级组织方式:把守卫案例收束成团队规范。
你最终会做出什么
最终案例是一套守卫 AI 模板:
| 状态 | 任务 | 跳转 |
|---|---|---|
| Idle | 等待、播放站岗姿态 | 等待结束去 Patrol,看见玩家去 Alert |
| Patrol | Move To 巡逻点 | 到达点后回 Idle,看见玩家去 Alert |
| Alert | 面向玩家、短暂确认 | 仍看见玩家去 Chase,丢失则 Search |
| Chase | Move To 玩家当前位置 | 距离太远去 Search,靠近进入 Combat 入口 |
| Search | 去最后看到的位置、等待 | 搜索失败 Return |
| Return | 回出生岗位 | 到达后 Idle |
这不是为了做一个完美游戏 AI,而是为了把 StateTree 里最常用的功能全部走一遍。
源码依据
UE5.8 的 UStateTree 是 UDataAsset,保存编辑器定义和运行时 baked 格式。FStateTreeTaskBase 注释写得很直接:Task 是 active state 中执行的逻辑。FStateTreeConditionBase 提供 TestCondition。UStateTreeComponent 继承 UBrainComponent,负责 StartLogic、TickComponent、SendStateTreeEvent 和实例数据。UStateTreeAIComponent 是专门跑在 AIController 上的组件,Schema 保证能访问 AIController。
架构地图
从项目架构看,StateTree 不应该孤零零存在。它上面接 AIController、输入事件和团队已有的决策入口;它中间维护状态、任务、跳转和绑定;它下面调用导航、动画、GAS、感知、EQS、SmartObject 或 Mass。读这组文章时,可以始终把它当成“行为流程编排层”,而不是感知系统、移动系统或动画系统本身。
项目落地
写 StateTree 前,先画状态表。不要一上来就加节点。每一行写清楚:状态名、进入后做什么、成功/失败条件、能跳到哪里、需要哪些数据。状态表能写清楚,StateTree 才会清楚。状态表都写不清楚,编辑器里只会得到一团看起来很高级的混乱。
常见坑
不要把 StateTree 当万能蓝图。它适合组织状态和状态里的任务,不适合塞一切业务。不要让多个系统同时控制同一个 AI 的移动,比如 Behavior Tree 也 MoveTo,StateTree 也 MoveTo。不要把变量来源藏在 Task 里到处读 Actor,优先用参数、Evaluator 和绑定把数据流显式摆出来。
源码路径索引
Engine/Plugins/Runtime/StateTree/Source/StateTreeModule/Public/StateTree.hEngine/Plugins/Runtime/StateTree/Source/StateTreeModule/Public/StateTreeTaskBase.hEngine/Plugins/Runtime/GameplayStateTree/Source/GameplayStateTreeModule/Public/Components/StateTreeComponent.hEngine/Plugins/Runtime/GameplayStateTree/Source/GameplayStateTreeModule/Public/Components/StateTreeAIComponent.h