UE5.8 Mass Framework 专题系列

UE5.8 Mass 专题(五):Trait、Entity Config、Template 与 Spawner

从 UMassEntityTraitBase、FMassEntityConfig、UMassEntityConfigAsset、FMassEntityTemplate、Template Registry、AMassSpawner 和 SpawnDataGenerator 讲配置化生成。

总览

如果只看 MassEntity,Mass 很像纯 C++ ECS;真正让团队能用起来的是 MassSpawner 模块。它把 Fragment 组合包装成 UMassEntityTraitBase,再由 FMassEntityConfigUMassEntityConfigAsset 组合成模板,最后用 AMassSpawner 和 SpawnDataGenerator 在地图里批量生成实体。设计师配置的是 Trait 和 Config,程序员维护的是 Trait 如何构建 Template。

UE5.8 的 UMassEntityTraitBase 注释写得很清楚:Trait 是一组 Fragment,形成一个对最终用户有意义的逻辑特性,例如 replication、visualization。BuildTemplate 用来向实体模板追加数据,也可以把资产引用转成更轻的共享索引。

UE5.8 Mass 专题(五):Trait、Entity Config、Template 与 Spawner 配图
Trait 把代码里的 Fragment 组合包装成设计师可配置的特性;Spawner 再把模板和位置生成器批量实例化。

源码依据

MassEntityTraitBase.h 定义 BuildTemplateValidateTemplateDestroyTemplateValidTargetConfigMassEntityConfigAsset.hFMassEntityConfig 支持 Parent、Traits、GetCombinedTraitsGetOrCreateEntityTemplateValidateEntityTemplate,适合做配置继承。MassSpawner.hAMassSpawner 提供 EntityTypesSpawnDataGeneratorsbAutoSpawnOnBeginPlayDoSpawningDoDespawningScaleSpawningCount 和 Debug Spawn/Clear。

架构分析

Trait 是 Mass 的“可配置模块边界”。一个移动 Trait 不应该自己生成 UI,不应该做业务决策,只负责给模板加移动所需的 Fragment/Tag/Shared Fragment。一个 Representation Trait 也不该决定实体去哪,只负责表现参数、Actor 管理类、ISM 描述和 LOD 参数。这样 Config Asset 才能像积木一样组合。

Config 的 Parent 机制适合做“基础人群类型 + 细分职业”。例如 DA_CrowdBase 提供 Transform、Movement、ZoneGraph、LOD;DA_OfficeWorker 继承后加 StateTree 和办公楼目的地参数;DA_Tourist 继承后加拍照、停留和 SmartObject 标签。不要把所有变化都做成一个巨大 Trait 的枚举,否则编辑器里看似少资产,实际是把组合性藏进代码分支。

使用案例

自定义一个顾客 Trait,给实体加入顾客数据和默认 Tag:

UCLASS(meta=(DisplayName="Shopper"))
class UShopperTrait : public UMassEntityTraitBase
{
    GENERATED_BODY()

protected:
    virtual void BuildTemplate(FMassEntityTemplateBuildContext& BuildContext, const UWorld& World) const override
    {
        BuildContext.AddFragment<FShopperIntentFragment>();
        BuildContext.AddFragment<FShopperBudgetFragment>();
        BuildContext.AddTag<FShopperCustomerTag>();

        FShopperSharedSettings Settings;
        Settings.QueueTolerance = QueueTolerance;
        Settings.DefaultPatience = DefaultPatience;
        BuildContext.AddConstSharedFragment(Settings);
    }

    UPROPERTY(EditAnywhere, Category="Shopper")
    float QueueTolerance = 120.0f;

    UPROPERTY(EditAnywhere, Category="Shopper")
    float DefaultPatience = 1.0f;
};

编辑器使用路径:

  1. 启用 MassEntity、MassSpawner、MassMovement、MassRepresentation、MassAI 相关插件。
  2. 创建 Mass Entity Config 资产,例如 DA_ShopperConfig
  3. 在 Traits 中添加 Transform、Movement、ZoneGraph Navigation、Representation、StateTree、自定义 Shopper Trait。
  4. 在场景放置 AMassSpawner,把 Entity Type 指向 DA_ShopperConfig
  5. 添加 SpawnDataGenerator,例如区域生成、ZoneGraph 生成或自定义生成器。
  6. 勾选 BeginPlay 自动生成,或在编辑器里用 DEBUG Spawn 验证。

项目落地

推荐每个 Trait 都写 ValidateTemplate,检查依赖是否存在。比如 Shopper Trait 依赖 Transform 和 Movement,就在验证里补充 Required Type 或报错。这样内容侧少配一个 Trait 时,错误能在资产校验阶段暴露,而不是运行时 Processor 查询不到实体。

常见坑

不要在 Trait 里启动运行时逻辑,Trait 的职责是构建模板。不要在 Config 层塞互斥 Trait 而不做验证,例如同时配置 CodeDrivenMovement 和 CustomMovement。不要忘记 ValidTargetConfig,有些 Trait 只该在服务器或客户端生效。不要把 Spawner 当对象池万能入口,生产项目还要考虑流送、World Partition、密度缩放和销毁策略。

源码路径索引

  • MassSpawner/Public/MassEntityTraitBase.h
  • MassSpawner/Public/MassEntityConfigAsset.h
  • MassSpawner/Public/MassEntityTemplate.h
  • MassSpawner/Public/MassSpawner.h