Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Mass学习知识点

一、前置知识

1.1 必备基础

  • C++ 现代特性(模板、CRTP、移动语义)
  • UE5 基础(Actor/Component、Subsystem、GameplayTag)
  • 数据结构基础(内存布局、缓存友好性概念)

1.2 有帮助的背景知识

  • ECS 架构概念(Entity、Component、System 的关系)
  • DOD(Data-Oriented Design)思想
  • 多线程基础(竞争条件、读写锁)

二、Mass 核心架构

2.1 数据原语

  • Fragment:数据存储单元,Plain Struct,无虚函数限制
  • Tag:零大小标记,触发 Archetype 分类
  • Chunk Fragment:Chunk 粒度共享数据
  • Shared Fragment:跨 Archetype 的只读共享配置

2.2 实体组织

  • Entity:轻量句柄(FMassEntityHandle),无实体数据
  • Archetype:Fragment 组合的唯一类型,决定内存布局
  • Chunk:Archetype 下的内存块,默认容纳 128 个实体
  • Archetype 迁移机制:Tag/Fragment 变化时的数据搬运代价

2.3 逻辑单元

  • Processor:继承 UMassProcessor,声明 Query + 实现 Execute
  • ProcessorGroup:Processor 的分组、排序与依赖声明
  • Processing Phase:帧内执行阶段(PrePhysics / Physics / PostPhysics / FrameEnd)

对应游戏逻辑来说,各 Phase 的职责:

  1. PrePhysics — 最常用的逻辑阶段,大多数 Processor 放这里

    • 输入处理、AI决策
    • 子弹生成/销毁判断
    • 速度/方向更新
    • 生命周期计时(ElapsedTime += DeltaTime)
  2. StartPhysics — 把数据“喂“给物理引擎之前

    • 将 Mass 数据同步到 Chaos/PhysX(如果你用了物理 Actor 桥接)
    • 设置物理 body 的速度、位置
  3. DuringPhysics — 物理模拟并行运行期间,CPU 空闲时做的事

    • 纯计算、无副作用的任务(动画预算、LOD计算)
    • 不能读写物理结果,因为物理还没算完
    • bullet hell 场景基本不用这个
  4. EndPhysics — 物理结果已出来,可以读取

    • 从物理引擎回读碰撞结果
    • 处理碰撞响应(子弹击中判定、伤害计算)
    • 销毁被标记的实体
  5. PostPhysics — 所有逻辑和物理都结束后

    • 同步 Transform 到渲染(ISM/Niagara buffer 更新)
    • Debug Draw
    • 统计数据收集
  6. FrameEnd — 帧末尾清理

    • 清理临时数据
    • 重置帧标记 flag

自定义碰撞可以参考下面的processor的phase:

PrePhysics:   BulletLifetimeProcessor, BulletMovementProcessor
EndPhysics:   BulletHitProcessor (碰撞结果处理)
PostPhysics:  BulletRenderSyncProcessor, BulletDebugProcessor

2.4 核心管理器

  • FMassEntityManager:实体增删改查的核心 API
  • UMassEntitySubsystem:全局入口,获取 EntityManager
  • FMassExecutionContext:Processor 执行时的上下文,含延迟命令队列

三、Query 系统

3.1 Query 声明

  • FMassEntityQuery 的构造与注册
  • 访问类型:EMassFragmentAccess::ReadOnly / ReadWrite
  • 存在性过滤:EMassFragmentPresence::All / Any / None / Optional

3.2 Query 遍历

  • ForEachEntityChunk:Chunk 级批量遍历(推荐)
  • GetMutableFragmentView / GetFragmentView:获取 Fragment 数组视图
  • GetEntityCollection:获取实体句柄列表

3.3 延迟命令

  • FMassExecutionContext::Defer():安全的帧内结构变更
  • AddFragment / RemoveFragment / AddTag / RemoveTag 的延迟版本
  • 为什么不能在遍历中直接修改结构(迭代器失效问题)

四、内存模型与性能

4.1 内存布局

  • SoA(Struct of Arrays)vs AoS(Array of Structs)
  • Fragment 在 Chunk 内的连续存储方式
  • 缓存行(Cache Line)与批量处理的关系

4.2 性能关键点

  • Archetype 数量控制:避免 Fragment 组合爆炸
  • Tag 使用代价:每次 AddTag / RemoveTag 都触发实体迁移
  • Chunk 利用率:实体数量与 Chunk 填充率的关系
  • Processor 依赖图:减少不必要的同步点

4.3 多线程模型

  • Processor 并行执行条件(无写冲突)
  • ExecutionFlags 控制线程策略
  • 共享资源访问:Subsystem 的线程安全注意事项

五、实体生命周期管理

5.1 创建

  • BatchCreateEntities:批量创建推荐方式
  • FMassEntityTemplateFMassArchetypeHandle
  • 初始化 Fragment 数据的时机

5.2 修改

  • 结构修改(Fragment / Tag 增删)vs 数据修改
  • FMassCommandBuffer:批量延迟命令的底层机制
  • 帧内修改 vs 跨帧修改

5.3 销毁

  • DestroyEntity / BatchDestroyEntities
  • 销毁时的内存回收策略(Chunk 空洞处理)
  • 与 Actor 销毁的同步问题

六、与 UE 生态集成

6.1 Mass + Actor 桥接

  • FMassActorFragment:Entity 持有 Actor 引用
  • UMassActorSubsystem:Actor 到 Entity 的反向查找
  • 生命周期同步:Actor Spawn / Destroy 与 Entity 的对应

6.2 Mass + Niagara

  • FNiagaraDataInterfaceMassEntity:将 Fragment 数据暴露给 GPU
  • Data Interface 的读写同步机制
  • 大规模粒子渲染的典型架构(CPU 逻辑 + GPU 渲染分离)

6.3 Mass + StateTree

  • StateTree 作为 Mass 的 AI 行为驱动
  • FMassStateTreeFragment 的使用
  • 状态机与 ECS 的结合点

6.4 Mass Signal 系统

  • UMassSignalSubsystem:实体间事件通知
  • Signal 的发送与订阅机制
  • 与传统 Delegate 的区别和适用场景

七、官方插件解析

7.1 MassGameplay 插件

  • UMassMovementProcessor:内置移动处理
  • UMassLookAtProcessor:朝向计算
  • 常用内置 Fragment 速查

7.2 MassAI 插件

  • ZoneGraph 与 Mass 的配合
  • Mass Crowd 人群系统架构
  • LOD 分级策略(高频 Processor → 低频 Processor → 纯数据)

7.3 MassTraffic 插件

  • 交通模拟的 Mass 实现思路
  • 可借鉴的大规模实体管理模式

八、调试与工具链

8.1 运行时调试

  • Mass Debugger:Archetype 分布、实体状态查看
  • Unreal Insights:Processor 执行时序分析
  • UE_MASS_EXECUTE_PROCESSOR_DEBUG 相关宏

8.2 常见问题排查

  • Entity 句柄失效(Handle Invalidation)
  • Processor 执行顺序不符合预期
  • Archetype 数量异常增长
  • 多线程数据竞争定位

8.3 单元测试

  • Mass 系统的可测试性设计
  • FMassEntityManager 在非 World 环境下测试 Processor

九、设计模式与最佳实践

  • 组合优于继承:Fragment 粒度设计原则
  • Tag 状态机:用 Tag 变化驱动行为切换
  • 批量操作优先:避免逐实体调用 API
  • 读写分离:将只读 Processor 和写 Processor 分开以最大化并行
  • 延迟销毁模式:用 Tag 标记 + 延迟批量销毁代替即时销毁
  • 配置与数据分离:用 Shared Fragment 存配置,Fragment 存状态

十、知识掌握自测

每个阶段完成后可以自问:

阶段自测问题
入门能否独立定义 Fragment、写一个 Processor 让实体移动?
进阶能否解释 Archetype 迁移的代价,并设计出避免频繁迁移的方案?
熟练能否将 Mass 与 Niagara 集成,实现万级实体的高性能渲染?
精通能否分析一个 Mass 系统的性能瓶颈,并给出优化方案?