总览
USmartObjectDefinition 是 Smart Object 的资产模板。它不代表关卡里的某一把椅子,而是代表“这种椅子能被怎么使用”。同一个 Definition 可以被很多 Actor 的 USmartObjectComponent 引用,每个实例的位置、注册句柄、运行时状态由 Subsystem 管。
资产结构
| 层级 | 保存什么 | 项目例子 |
|---|---|---|
| Definition | 通用能力、默认行为、对象级条件、默认参数 | SOD_Workbench_Craft |
| Slot | 可使用位置、朝向、Slot 级 Tag、Slot 行为、Slot 条件 | Craft_Left、Craft_Right |
| BehaviorDefinition | 使用时交给哪个行为框架执行 | GameplayBehavior、GameplayInteractions、Mass |
| DefinitionData | 给行为或工具读取的自定义结构 | 动画名、对齐规则、交互时长 |
| Parameters | Definition 变体覆盖 | 同一类工作台不同高度 |
使用案例
工作台最少两个 Slot:一个给 NPC 站在左侧打磨,一个给玩家站在前方交互。它们不应该做成两个 Actor,也不应该做成两个 Definition。更好的设计是一个 SOD_Workbench,两个 Slot:Use_PlayerFront 和 Use_NPCLeft。Slot 各自有 Offset、Rotation、ActivityTags 和 BehaviorDefinition。
门的设计不同。门通常只有一个或两个入口 Slot,但对象级 Preconditions 很重要:锁住、战斗中、需要钥匙、门另一侧被阻挡。也就是说,门更依赖 World Conditions 和 RuntimeTags,不是靠多 Slot 解决。
架构分析
FSmartObjectSlotDefinition 里 Offset 和 Rotation 是相对于对象的局部 Transform。GetSlotWorldTransform 会把 Slot 的局部位置乘上对象 Transform。这个设计允许你把同一个 Definition 放到很多 Actor 上,而不用复制每个世界坐标。
Tag 有三类最容易混:ActivityTags 表示“这个 Slot 支持什么活动”;UserTagFilter 表示“什么用户能使用”;RuntimeTags 表示运行时状态,例如 SO.State.Locked、SO.State.BusyByQuest。查询请求里的 ActivityRequirements 会匹配 ActivityTags,请求里的 UserTags 会被 UserTagFilter 检查。
Tag 规划
Activity.Sit
Activity.Work.Craft
Activity.Door.Open
Activity.Cover.Peek
User.Humanoid
User.Player
User.NPC.Civilian
User.NPC.Guard
SO.State.Locked
SO.State.DisabledByQuest
SO.State.NeedsRepair
命名时尽量让标签回答一个问题:Activity 回答“能做什么”,User 回答“谁能用”,State 回答“现在怎样”。不要用 Chair.Usable 这种混合语义。
项目落地
为每类 Smart Object 写一张资产合同表:Definition 名、Slot 列表、ActivityTags、UserTagFilter、BehaviorDefinition 类型、必须的 DefinitionData、是否支持多人、是否会被 Mass 使用。内容团队按表配置,程序按表写行为和验证工具。
常见坑
- 把所有对象都做成一个巨大 Definition:Definition 应该对应一种稳定交互语义。
- Slot 命名不表达方向:
Slot_01不如Use_Front、Sit_Left、Queue_Exit。 - 运行时状态写死在资产 Tag:锁门、任务禁用、维修中应该走 RuntimeTags 或 Enabled reason。
- DefinitionData 没版本意识:结构改字段后要考虑旧资产加载和编辑器校验。
- 同一 Slot 塞多个同类 BehaviorDefinition:源码里按类型取第一个,团队要规定唯一性。
源码依据
USmartObjectDefinition 继承 UDataAsset,保存 Slots、DefaultBehaviorDefinitions、UserTagFilter、Preconditions、ActivityTags、DefinitionData、Parameters 和 BindingCollection。FSmartObjectSlotDefinition 保存 Offset、Rotation、bEnabled、UserTagFilter、ActivityTags、RuntimeTags、SelectionPreconditions、BehaviorDefinitions 和 Slot 级 DefinitionData。源码还提供 ESmartObjectTagMergingPolicy 和 ESmartObjectTagFilteringPolicy 控制对象级和 Slot 级 Tag 如何组合。
源码路径索引
SmartObjectsModule/Public/SmartObjectDefinition.hSmartObjectsModule/Public/SmartObjectTypes.hSmartObjectsModule/Public/SmartObjectDefinitionReference.hSmartObjectsModule/Public/SmartObjectBindingCollection.h