MassBattle Docsv1.19.20

UMassBattleHostMonoProcessor

UCLASS Processor

Source/MassBattle/Public/Processors/MassBattleHostMonoProcessor.h

概述 Overview

全部六种宿主类型(Fx / Projectile / Loot / Actor / Sound / Agent)的合并宿主处理器。单查询 Any<六个 config fragment> + chunk 分派;每 tick 为每个宿主实体执行:① 层级变换解析(经 FHostHierarchy,支持 ExternalEntity 外部实体附着 / WorldAnchor / ParentHost 树形结构,含 mesh 倾斜匹配与速度/插值参数继承);② 生命周期(lifecycle 判定、父级失效的级联销毁 MarkSubtreeShouldDestroy 或脱离、池管理);③ 概率门控(按 Agent 行为状态计数插值生成概率);④ 初始生成与逐帧变换更新;⑤ resync 后的 UObject 刷新(bNeedsSpawnRefresh,只重发生成 op 不重跑概率)。所有 UObject 操作(Actor/Sound/非合批 FX)以 op 命令收集,经 MBH 的 ActorOps / FxOps / SoundOps / ProjectileOps / LootOps / HostEntityRecycleQueue 在游戏线程串行排空。另有 TickCpuInterp 每引擎帧运行的 CPU 插值通道(独立于 SimStages)。

Merged host processor for all six host types (Fx / Projectile / Loot / Actor / Sound / Agent). One query Any<six config fragments> with chunk dispatch; per tick, each host entity goes through: ① hierarchy transform resolution (via FHostHierarchy, supporting ExternalEntity attachment / WorldAnchor / ParentHost tree structure, mesh-tilt matching, and velocity / interp-param inheritance); ② lifecycle (destroy checks, parent-gone cascade MarkSubtreeShouldDestroy or unlink, pool management); ③ probability gate (spawn probability interpolated from per-behavior-state agent counts); ④ initial spawn and per-frame transform updates; ⑤ post-resync UObject refresh (bNeedsSpawnRefresh, re-emitting spawn ops without re-rolling probability). All UObject work (Actor/Sound/unbatched FX) is gathered as op commands and drained serially on the game thread through MBH's ActorOps / FxOps / SoundOps / ProjectileOps / LootOps / HostEntityRecycleQueue. TickCpuInterp additionally provides an every-engine-frame CPU interpolation channel (outside SimStages).

继承 Inheritance

UMassProcessor → UMassBattleHostMonoProcessor

公开方法 Public Methods

UMassBattleHostMonoProcessor 构造函数

构造函数。设置 bAutoRegisterWithProcessingPhases = false(手动派发)、bRequiresGameThreadExecution = true、ExecutionFlags = Standalone | Server | Client。

Constructor. Sets bAutoRegisterWithProcessingPhases = false (manually dispatched), bRequiresGameThreadExecution = true, and ExecutionFlags = Standalone | Server | Client.

Input

无参数。

No parameters.

Output

无返回值。副作用:注册为手动派发、游戏线程专用的处理器。

No return value. Side effect: registers as a manually-dispatched, game-thread-only processor.

ConfigureQueries virtual void

初始化两个查询。EntityQuery:Any<FFxConfig_Final, FProjectileConfig_Final, FSoundConfig_Final, FActorSpawnConfig_Final, FAgentHostConfig_Final, FLootConfig_Final>(MARW) + All<FHostHierarchy>(MARW) + Optional<FTracingShared>(MARO)。CpuInterpQuery(CPU 插值 FX 宿主轻量查询,每引擎帧运行,无子帧门控):All<FCpuInterpTag> + All<FHostHierarchy>(MARW) + Optional<FFxConfig_Final, FActorSpawnConfig_Final, FSoundConfig_Final>(MARO)。

Initializes two queries. EntityQuery: Any<FFxConfig_Final, FProjectileConfig_Final, FSoundConfig_Final, FActorSpawnConfig_Final, FAgentHostConfig_Final, FLootConfig_Final>(MARW) + All<FHostHierarchy>(MARW) + Optional<FTracingShared>(MARO). CpuInterpQuery (lightweight CPU-interp FX host query, runs every engine frame, no sub-frame gate): All<FCpuInterpTag> + All<FHostHierarchy>(MARW) + Optional<FFxConfig_Final, FActorSpawnConfig_Final, FSoundConfig_Final>(MARO).

Input
参数 Param类型 Type说明 Description
EntityManagerconst TSharedRef<FMassEntityManager>Mass 实体管理器,查询初始化目标。Mass entity manager; query initialization target.
Output

无返回值。副作用:两个查询注册进处理器。

No return value. Side effect: two queries registered with the processor.

Execute virtual void

每 tick 执行入口(只在 ESubFrame::Subtick2 运行——完整 move 阶段已执行,ops 携带本 tick 变换)。取 MB / MA / MP / MBH(任一缺失返回)。并行遍历中,每个根宿主(非 ParentHost 附着):① 层级解析:ExternalEntity 来源从附着实体读旋转/位置(应用 mesh tilt 以匹配 AgentRenderProcessor 的 AgentFacingRot),继承线性/角速度与插值参数(FVisualizing / FProjectileVisualizing / FLootVisualizing 分支);WorldAnchor 保持上次解析值;② 父级失效检测;③ 按类型 lifecycle(Actor/Fx/Sound/Projectile/Agent/Loot 六分支):池逻辑(bIsPooled 倒计时,过期无条件销毁,池可缩到 0)、附着更新(未生成或附着时重算 SpawnTransform、非附着已生成宿主发 Transform op、FX 分支写 FFxVisualizing 父级真值与配对实体变换)、销毁判定(LifeSpan 到期 / 父级失效级联 MarkSubtreeShouldDestroy / 非网络模式的 Idle 检查 / projectile-loot 的 Spawned 实体失效)、bNeedsSpawnRefresh 只重发生成 op、初始生成(概率门控:按 AgentBehaviorState 取对应 agent 计数,在 SpawnProbability XY→ZW 间插值,Config.RandomStream.FRand() 判定失败则 Reset+回收;FX 分支激活配对实体而非新建——零 observer 成本;池耗尽 fallback 入队 FxEntitySpawns)、计时器更新(Delay → LifeSpan 递减);④ 根处理后 WalkHostTree 递归子树:子节点相对变换乘父级解析变换、父级失效处理、同类 lifecycle、销毁时先 UnlinkHostChild;⑤ chunk 末把本地 ops append 到 MBH 六个队列。

Per-tick entry (runs only on ESubFrame::Subtick2 — the full move phase has completed, so ops carry current-tick transforms). Resolves MB / MA / MP / MBH (returns early if any missing). In the parallel traversal, each root host (not ParentHost-attached): ① hierarchy resolution: ExternalEntity sources read rotation/location from the attachment entity (applying mesh tilt to match AgentRenderProcessor's AgentFacingRot), inheriting linear/angular velocity and interp params (FVisualizing / FProjectileVisualizing / FLootVisualizing branches); WorldAnchor keeps the last resolved transform; ② parent-gone detection; ③ per-type lifecycle (Actor/Fx/Sound/Projectile/Agent/Loot branches): pool logic (bIsPooled countdown; expired idle entries destroyed unconditionally, pool may shrink to 0), attachment update (recompute SpawnTransform when unspawned or attached; un-attached spawned hosts emit Transform ops; the FX branch writes FFxVisualizing parent ground-truth and the paired entity's transform), destroy decisions (LifeSpan expiry / parent-gone cascade MarkSubtreeShouldDestroy / non-networked Idle check / projectile-loot spawned-entity invalidation), bNeedsSpawnRefresh re-emits spawn ops only, initial spawn (probability gate: pick the agent count by AgentBehaviorState, interpolate within SpawnProbability XY→ZW, fail via Config.RandomStream.FRand() → Reset + recycle; the FX branch activates the paired entity instead of creating one — zero observer cost; pool-exhausted fallback enqueues FxEntitySpawns), timer updates (Delay → LifeSpan countdown); ④ after root lifecycle, WalkHostTree recurses the subtree: child relative transform × parent resolved transform, parent-gone handling, same-kind lifecycle, UnlinkHostChild before destroy; ⑤ at chunk end, local ops are appended to MBH's six queues.

Input
参数 Param类型 Type说明 Description
EntityManagerFMassEntityManager&实体管理器。Entity manager.
ContextFMassExecutionContext&执行上下文,提供 fragment 视图与实体遍历。Execution context providing fragment views and entity iteration.
Output

无返回值。副作用:写各 config fragment 的 SpawnTransform / bSpawned / LifeSpan / bShouldDestroy 等;向 MBH.ActorOps / FxOps / SoundOps / ProjectileOps / LootOps / HostEntityRecycleQueue / FxEntitySpawns / FxCompletionCheckEntities 与 MB.EntitiesToDestroyQueue 写入;级联修改子树 FHostHierarchy。

No return value. Side effects: writes each config fragment's SpawnTransform / bSpawned / LifeSpan / bShouldDestroy; writes to MBH.ActorOps / FxOps / SoundOps / ProjectileOps / LootOps / HostEntityRecycleQueue / FxEntitySpawns / FxCompletionCheckEntities and MB.EntitiesToDestroyQueue; cascades changes to subtree FHostHierarchy.

TickCpuInterp void

所有 FCpuInterpTag 宿主(Fx/Actor/Sound)的逐引擎帧 CPU 插值入口,由子系统 Tick 调用,不经 SimStages 派发。并行段:每实体 FHostHierarchy.InterpState.Tick() 按解析的 ground-truth 变换/速度/插值参数推进插值;按类型分发——非合批 FX 与 Actor/Sound 把 InitialRelativeTransform * InterpXf 收集进 CpuInterpUObjectOps(成员 gatherer,持久地址保证 TLS 缓存正确),合批 FX 直接写 FFxVisualizing 与渲染批次槽数组(LocationArray_Attached 等)并置 bCpuInterpDirty 脏标志。纪律:插值写入纯渲染数据,绝不触碰模拟 fragment(避免帧率相关视觉状态泄漏进 sim 与 hash)。串行段:遍历所有 FxRenderers 的批次把脏数组经 SetNiagaraArray* 推给 Niagara;随后 Merge() 并按类型应用 UObject 变换(Actor 用 SetActorTransform、Sound 用 SetWorldLocationAndRotation、非合批 FX 用 SetWorldTransform)。

Every-engine-frame CPU interpolation entry for all FCpuInterpTag hosts (Fx/Actor/Sound), called from the subsystem Tick, not via SimStages dispatch. Parallel phase: per entity, FHostHierarchy.InterpState.Tick() advances interpolation from the resolved ground-truth transform / velocities / interp params; per-type dispatch — unbatched FX and Actor/Sound gather InitialRelativeTransform * InterpXf into CpuInterpUObjectOps (member gatherer, stable address keeps TLS cache correct); batched FX writes FFxVisualizing and the render-batch slot arrays (LocationArray_Attached etc.) and sets the bCpuInterpDirty flag. Rule: interp writes are PURE RENDER DATA — never touch sim fragments (frame-rate-dependent visual state must not leak into sim or hash). Serial phase: push dirty batches to Niagara via SetNiagaraArray* across all FxRenderers, then Merge() and apply UObject transforms by type (Actor via SetActorTransform, Sound via SetWorldLocationAndRotation, unbatched FX via SetWorldTransform).

Input
参数 Param类型 Type说明 Description
EngineDeltaTimefloat引擎帧时间步长(秒);小于 KINDA_SMALL_NUMBER 时钳到 0.001f。Engine frame delta time in seconds; clamped to 0.001f below KINDA_SMALL_NUMBER.
Output

无返回值。副作用:推进 FHostHierarchy.InterpState;写 FFxVisualizing 与渲染批次数组;对 Actor/Sound/非合批 FX 应用 UObject 变换。

No return value. Side effects: advances FHostHierarchy.InterpState; writes FFxVisualizing and render-batch arrays; applies UObject transforms to Actor/Sound/unbatched FX.

成员变量 Members

FCpuInterpUObjectOp struct (头文件公开)

并行 TickCpuInterp 期间收集的 UObject 变换操作,游戏线程串行应用。Type:0=Actor,1=Sound,2=非合批 FX;WorldXf 为目标世界变换。

UObject transform op gathered during parallel TickCpuInterp, applied serially on the game thread. Type: 0=Actor, 1=Sound, 2=unbatched FX; WorldXf is the target world transform.

EntityQuery FMassEntityQuery (private)

主宿主查询(Any<六个 config>),组合见 ConfigureQueries。

Main host query (Any<six configs>); composition in ConfigureQueries.

CpuInterpQuery FMassEntityQuery (private)

CPU 插值 FX 宿主轻量查询,每引擎帧运行(无子帧门控)。

Lightweight query for CPU-interp FX hosts, runs every engine frame (no sub-frame gate).

CpuInterpUObjectOps FParallelGatherer<FCpuInterpUObjectOp> (private)

UObject 变换操作的持久收集器。必须是成员——FParallelGatherer 的 thread_local 缓存以实例地址为键,局部变量会被栈复用导致误命中缓存、Merge 为空。合批 FX 的 Niagara 推送改用脏标志(无需 gather)。每帧 TickCpuInterp 内 Reset/Merge。

Persistent gatherer for UObject transform ops. Must be a member — FParallelGatherer's thread_local cache keys on instance address; locals get stack-reused → false cache hits → empty Merge. Batched-FX Niagara push uses a dirty flag instead (no gather). Reset/Merge per frame inside TickCpuInterp.

管线角色 Pipeline Role

注册于 UMassBattleSubsystem 的 SimStages[5](最后阶段),只在 Subtick2 引擎帧运行——全部 move 分区已执行,读到的实体位置是完整 move 阶段的产物,挂点携带本 tick 变换(CPU 插值仍跨引擎帧平滑)。Execute 收集的 ops 由 UMassBattleHostSubsystem 在游戏线程串行排空(ProcessHostOpsQueues);spawn 的实体(UObject actor / Niagara / projectile / loot)进入各自的池与子系统。TickCpuInterp 每引擎帧由子系统 Tick 直接调用,与 SimStages 解耦。

Registered in UMassBattleSubsystem's SimStages[5] (last stage), running only on the Subtick2 engine tick — after all move partitions, so entity positions read here are the full move phase's output and attachments carry current-tick transforms (CPU interpolation still smooths across engine frames). Ops gathered by Execute are drained serially on the game thread by UMassBattleHostSubsystem (ProcessHostOpsQueues); spawned entities (UObject actors / Niagara / projectiles / loot) enter their respective pools and subsystems. TickCpuInterp is called every engine frame by the subsystem Tick, decoupled from SimStages.