UE Mass Entity 是一份面向虚幻引擎 C++ 开发者的技能文档,主题是在 Unreal Engine 中编写或调试 Mass Entity ECS 代码。目标引擎版本为 UE 5.8,文中 API 均针对 5.8 头文件验证,旧写法列在“Deprecated — do not use”下。
用途 Mass 是一种原型(archetype)实体组件系统,用于以缓存友好的数据布局和多线程处理器模拟数千个智能体。核心位于始终可用的运行时模块 MassEntity 和 MassCore(外加 MassSignals、MassEngine);面向玩法的部分(生成、表示、移动、LOD、复制、Actor 桥接)来自 MassGameplay 插件(5.8 中为实验性),导航与行为来自 MassAI(5.8 中为实验性)和 MassCrowd(5.8 中为实验性)。
主要能力 文档按请求类型给出导航:Build.cs 与包含文件、声明片段/标签/共享数据、创建销毁实体与直接变更、编写处理器与调度阶段、选择实体与过滤、循环中读写片段数据、迭代期间增删片段、响应片段或标签的增删、处理器外的单实体访问与流式构建、父子链接与原型分组、Traits 与配置资产及 AMassSpawner、ISM 渲染与 LOD 及 Actor 提升、人群与车道及实体 AI。更长的模板见 mass-entity-patterns.md,内置类型与字段见 mass-fragment-reference.md。
模块与 Build.cs 没有需要启用的 MassEntity 插件。MassEntity 和 MassCore 是随引擎发布的运行时模块,加入 Build.cs 即可链接。只有玩法层是插件,必须在 .uproject 中启用。文档给出了 PublicDependencyModuleNames 的示例列表,包含 Core、CoreUObject、Engine、MassEntity、MassCore、MassSignals、MassCommon、MassSpawner、MassMovement、MassRepresentation、MassActors、MassNavigation。移入 MassCore 的包含路径带 Mass/ 命名空间,如 Mass/EntityElementTypes.h、Mass/EntityFragments.h、Mass/EntityHandle.h、Mass/ExternalSubsystemTraits.h、Mass/ArchetypeGroup.h。
片段、标签与原型 文档列出核心概念及其基类:Entity 使用 FMassEntityHandle(索引加序列号身份句柄);Fragment 使用 FMassFragment(每实体可变数据);稀疏片段使用 FMassSparseFragment(存储在原型之外,添加时不移动实体);Tag 使用 FMassTag(零尺寸标记,用于过滤);稀疏标签使用 FMassSparseTag(增删不改变原型);块片段使用 FMassChunkFragment(每个内存块一个实例);共享片段使用 FMassSharedFragment(被引用实体共享的可变值);常量共享片段使用 FMassConstSharedFragment(不可变共享配置);原型使用 FMassArchetypeHandle(唯一的片段/标签组合)。所有这些都派生自 FMassElement,声明于 Mass/EntityElementTypes.h。文档给出了 FMyHealthFragment、FMyAliveTag、FMyDeadTag、FMySquadSharedFragment 的示例代码。相同组合的实体共享一个原型,每种片段类型按块连续存储。增删片段或标签会把实体移到另一个原型,因此迭代期间结构变更被延迟。稀疏片段和稀疏标签正是为避免这种移动而存在。
FMassEntityManager FMassEntityManager 不是 UObject,而是派生自 TSharedFromThis<FMassEntityManager> 和 FGCObject 的结构体。可通过 UMassEntitySubsystem 或 UE::Mass::Utils 获取。文档给出创建实体、预留实体、批量创建、销毁实体的示例代码,并说明 FMassEntityHandle::IsSet() 只报告索引和序列号非零,判断实体是否真实存在需使用管理器的 IsEntityValid、IsEntityBuilt、IsEntityActive。在处理器迭代之外,直接结构变更合法;add/tag/swap 调用接受 TNotNull<const UScriptStruct*>,应传 T::StaticStruct()。实体存储是并发的,FMassEntityManager::Initialize 接受 FMassEntityManager_InitParams_Concurrent 并构建 FConcurrentEntityStorage。
UMassProcessor 文档说明应子类化 UMassProcessor,用 *this 构造查询以自我注册,并精确重写两个虚函数。给出 UMyMovementProcessor 的头文件与实现示例,包括 ProcessingPhase、ExecutionFlags、ExecutionOrder.ExecuteInGroup、ExecuteAfter、bRequiresGameThreadExecution 的设置。列出 EMassProcessingPhase 的取值(PrePhysics、StartPhysics、DuringPhysics、EndPhysics、PostPhysics、FrameEnd、MAX)和 EProcessorExecutionFlags 的取值。FMassProcessorExecutionOrder 包含 ExecuteInGroup 以及 ExecuteBefore、ExecuteAfter 数组;处理器名称是去掉 U 前缀的类 FName,拼错会静默丢失排序。命名组来自 UE::Mass::ProcessorGroupNames。
FMassEntityQuery 要求在 ConfigureQueries 中声明,绝不在构造函数中声明。文档给出 AddRequirement、AddTagRequirement、AddSharedRequirement、AddConstSharedRequirement、AddSubsystemRequirement 的示例,并列出 EMassFragmentAccess(None、ReadOnly、ReadWrite)和 EMassFragmentPresence(All、Any、None、Optional)的含义。AddChunkRequirement 绑定块片段,SetChunkFilter 接受每块求值一次的函数。
迭代与 FMassExecutionContext 文档给出 Execute 中 ForEachEntityChunk 的示例,lambda 只接受 FMassExecutionContext&,没有实体管理器参数。其他访问器包括 GetEntities、GetFragmentView、GetMutableFragmentView、GetChunkFragment、GetConstSharedFragment、GetMutableSharedFragment、GetSubsystem、GetMutableSubsystem 和 Defer。并行使用 ParallelForEachEntityChunk,时间切片使用带 UE::Mass::FExecutionLimiter 的重载,限制器需作为处理器成员跨帧保持存活。
延迟命令 在 ForEachEntityChunk 内绝不通过实体管理器变更组合,应使用 Context.Defer() 排队。文档给出 SwapTags、RemoveFragment 的示例,列出 FMassCommandBuffer 的便捷调用,以及通过 PushCommand 添加带值片段、推送任意延迟工作、子类化 FMassBatchedCommand 的方式。命令按 EMassCommandOperationType 桶刷新,顺序为 Create → Add → ChangeComposition → Set → Remove 和 Destroy → None。
UMassObserverProcessor 观察者在被观察对象变化时运行(原文在此处截断,后续内容暂未提供)。
适用场景与限制 适用于需要模拟数千个智能体、追求缓存友好数据布局与多线程处理的虚幻引擎 C++ 项目。限制方面:MassGameplay、MassAI、MassCrowd 在 5.8 中为实验性;结构变更在迭代期间必须延迟;处理器名称拼写错误会静默丢失排序;时间切片限制器不感知调用之间创建或销毁的实体。