总览
Smart Object 可以先理解成 世界里的可使用能力点:椅子不是只放一个 Mesh,工作台不是只放一个 Actor,门也不是只暴露一个 Interact 函数。它们都可以把“我有哪些可用位置、谁能用我、怎么找到我、用之前怎么占位、开始用时执行什么行为、用完怎么释放”写成数据和运行时状态。
一句话心智模型:USmartObjectDefinition 描述“这个对象能被怎么用”,FSmartObjectSlotDefinition 描述“具体站哪、朝哪、干什么”,USmartObjectComponent 把 Definition 挂到世界里的 Actor 上,USmartObjectSubsystem 负责注册、空间查询、筛选、Claim、Use 和 Release,AI/StateTree/Mass 只是不同的用户入口。
源码里的五个核心名先记住:USmartObjectDefinition、USmartObjectComponent、USmartObjectSubsystem、FSmartObjectRequest、FSmartObjectClaimHandle。读懂这五个,Smart Object 的 80% 心智模型就立住了。
架构地图
最小运行链路是:关卡里一个 Actor 挂 USmartObjectComponent,组件引用一个 USmartObjectDefinition,BeginPlay 注册进 USmartObjectSubsystem;AI 用 FSmartObjectRequest 搜索范围和过滤条件,得到 FSmartObjectRequestResult;真正要使用前先把 Slot 标记为 Claimed,移动到入口或 Slot Transform,开始行为时 MarkSlotAsOccupied,用完或中断时 MarkSlotAsFree。
SmartObject Actor
-> USmartObjectComponent
-> USmartObjectDefinition
-> Slot / ActivityTags / UserTagFilter / BehaviorDefinitions
-> USmartObjectSubsystem
-> FindSmartObject / MarkSlotAsClaimed / MarkSlotAsOccupied / MarkSlotAsFree
-> Behavior Tree / GameplayBehavior / GameplayInteractions StateTree / Mass
专题分篇目录
| 篇章 | 你会学到什么 | 读完能做什么 |
|---|---|---|
| 一 | 先做一个能用的椅子 | 从插件、Definition、Slot 到 AI Claim/Use 跑通闭环 |
| 二 | Definition、Slot、Tag、Data | 会设计一个可维护的 SmartObjectDefinition |
| 三 | 查找与空间索引 | 会写查询范围、ActivityRequirements、UserTags 和过滤 |
| 四 | Claim、Use、Release 生命周期 | 防止多个 AI 抢同一个点,能正确释放 |
| 五 | 行为怎么执行 | 用 GameplayBehavior 或自定义 BehaviorDefinition 驱动动画和逻辑 |
| 六 | 蓝图、C++、EQS 和 Behavior Tree | 会用 BTTask_FindAndUseGameplayBehaviorSmartObject 和 C++ API |
| 七 | World Conditions 和动态可用性 | 会做门锁、阵营、任务状态、白天黑夜等可用条件 |
| 八 | StateTree 与 GameplayInteractions | 会用 StateTree 管交互流程、Slot 事件和回退 |
| 九 | Mass SmartObjects | 会把 Smart Object 接入人群系统和 ZoneGraph |
| 十 | 生产落地 | 会规划命名、Tag、多人、World Partition、调试和性能 |
什么时候该用
适合用 Smart Object 的场景:AI 需要在世界里找“可用点”,并且这个点不只是一个位置,还包含使用条件、占用状态、动画/行为定义和调试信息。典型例子是椅子、工作台、门、掩体、攀爬点、摊位、队列点、电梯按钮、医疗站、NPC 闲逛点。
暂时不必用的场景:只有玩家靠近按 E 的单次交互,没有 AI 找点,也没有并发占用和筛选条件。那普通 Actor 交互组件就够了。Smart Object 的优势在“很多使用者、很多对象、需要查询和占用管理”的复杂度里。
项目落地
第一轮不要从 Mass 人群开始。先做一个 Actor 级案例:SO_Chair 定义一个坐下 Slot,AI 能找到、Claim、MoveTo、播放坐下行为、结束后释放。这个闭环调通后,再把同样的结构复制到工作台、门、队列点,最后再接 StateTree 或 Mass。
常见坑
- 把 Smart Object 当 Interact 组件:它真正强的是查找、筛选、占用和行为数据,不只是触发事件。
- 忘记 Release:Slot 会停在 Claimed 或 Occupied,后续 AI 永远找不到。
- Tag 没规划:ActivityTags、UserTags、RuntimeTags、World Conditions 混着用,排查很痛苦。
- Definition 和实例混淆:Definition 是资产模板,Component/Subsystem 里才有运行时位置和占用状态。
- 一上来接 Mass:Mass 链路更长,先用普通 AI 把 Definition 和生命周期理解透。
源码依据
SmartObjects.uplugin 的描述是“Support for ambient life populating the game world”,默认不启用,Runtime 模块是 SmartObjectsModule。核心 API 在 USmartObjectSubsystem:注册、查询、Slot 条件过滤、入口位置、Claim、Occupied、Free、Tag 和事件都在这里聚合。USmartObjectDefinition 继承 UDataAsset,保存 Slots、DefaultBehaviorDefinitions、Preconditions、ActivityTags、UserTagFilter、DefinitionData 和参数。
源码路径索引
Engine/Plugins/Runtime/SmartObjects/SmartObjects.upluginSmartObjectsModule/Public/SmartObjectDefinition.hSmartObjectsModule/Public/SmartObjectComponent.hSmartObjectsModule/Public/SmartObjectSubsystem.hSmartObjectsModule/Public/SmartObjectRuntime.hMassSmartObjects/Public/MassSmartObjectFragments.h