MassBattle Docsv1.19.20

UMassBattleAgentRenderProcessor

UCLASS Processor

Source/MassBattle/Public/Processors/MassBattleAgentRenderProcessor.h

概述 Overview

Agent 渲染的统一处理器,合并了原 MassBattleAgentLODProcessor(屏幕尺寸 LOD 选择与 Actor/Particle 表示切换)、MassBattleAgentAnimationProcessor(三层动画混合状态机与逐帧推进)与 MassBattleAgentRenderProcessor(渲染数据打包)。模拟帧执行:标签清洗 → LOD 选择 → 动画状态机(状态判定 / UpdateAnimBlendLevel1/2/3 / AdvanceFrame)→ 渲染数据打包(位压缩编码,parent+relative 或旧模型)→ 注册 / GC / Niagara 推送 / NDC TextPop。渲染只在 Subtick3 子帧执行,其它引擎帧跳过(Niagara GPU 自插值)。纪律:渲染阶段零 RNG 消耗——动画槽位完全由模拟侧选取并进快照,渲染状态机不得重置/重选,否则双端 RandomStream 游标发散触发 resync。

Unified render processor for agents, merging the former MassBattleAgentLODProcessor (screen-size LOD selection and Actor/Particle representation switching), MassBattleAgentAnimationProcessor (three-layer anim blend state machine with per-frame advancement), and MassBattleAgentRenderProcessor (render data packing). On sim ticks it runs: flag cleanup → LOD selection → anim state machine (state decision / UpdateAnimBlendLevel1/2/3 / AdvanceFrame) → render data packing (bit-packed encoding, parent+relative or old model) → registration / GC / Niagara push / NDC TextPop. Rendering runs only on the Subtick3 sub-frame; other engine ticks skip (Niagara self-interpolates on GPU). Rule: zero RNG consumption in render — anim slots are picked entirely on the sim side and restored from the snapshot; the render state machine must never reset/repick them, or RandomStream cursor divergence (a hash field) trips the resync loop.

继承 Inheritance

UMassProcessor → UMassBattleAgentRenderProcessor

公开方法 Public Methods

UMassBattleAgentRenderProcessor 构造函数

构造函数。设置 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

初始化实体查询:All<FAgentTag> + Optional<FAppearingTag, FDyingTag> + All<FSubType, FStyleType, FTeam, FLocating, FRotating, FCollider, FVisualize, FHealth, FHealthBar, FAppear, FAttack, FHit, FDeath, FMove, FDefence, FDebuffing, FAgentEvent, FAgentDebug, FLODShared, FAnimShared, FTracingShared>(MARO) + All<FEntityFlagFragment, FStatistics, FDeterminism, FScaling, FVisualizing, FTextPop, FAttacking, FMoving, FAnimating>(MARW)。

Initializes the entity query: All<FAgentTag> + Optional<FAppearingTag, FDyingTag> + All<FSubType, FStyleType, FTeam, FLocating, FRotating, FCollider, FVisualize, FHealth, FHealthBar, FAppear, FAttack, FHit, FDeath, FMove, FDefence, FDebuffing, FAgentEvent, FAgentDebug, FLODShared, FAnimShared, FTracingShared>(MARO) + All<FEntityFlagFragment, FStatistics, FDeterminism, FScaling, FVisualizing, FTextPop, FAttacking, FMoving, FAnimating>(MARW).

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

无返回值。副作用:EntityQuery 注册进处理器。

No return value. Side effect: EntityQuery registered with the processor.

Execute virtual void

每 tick 执行入口。取 MB / MA / MS(缺失返回),只在 ESubFrame::Subtick3 渲染。流程:① 重置槽位状态(并行):FreeSlotArray / IsHiddenArray / UniqueIDArray(身份令牌,GPU 对令牌变化槽位跳变);② 槽位冷却(仅模拟帧):最近释放槽位锁定 PoollingCoolDown 秒,保证 GPU 看到 IsHidden 间隔;③ 逐实体更新(并行):模拟帧执行渲染开关(FVisualize.bEnable ↔ NotRendering / Rendering 旗标切换)、Montage 结束回退(非循环蒙太奇播完回 PreviousAnimState)、LOD 选择(相机距离 → 屏幕尺寸 ScalingRadius / Distance × ProjectionFactor,五档 FLODData 选最高命中档,无命中用最小 ScreenSize 兜底;Actor 表示 ↔ Particle 表示切换经 MS.ActorSpawnRequestQueue / ActorRecycleQueue)、动画旗标清洗(DeathAnim/AppearAnim/AttackAnim/HitAnim 与对应状态一致化)、动画状态判定(PauseAnimChange / Montage / Dying / Appearing / Attacking / Falling(延迟)/ BeingHit / Move 速度阈值 / Idle;Idle/Move 归一为 BS_IdleMove 混合)、状态变更事件(OnAnimStateChangeQueue,带 AnimData/PlayRate/进度)、攻速减速(Defence.bCanSlowATKSpeed 时取 SlowCausers 最大减速强度)、反向帧外推抑制(bMoveCanReverse 时反向/翻转后 0.25s 用 raw 帧)、三层 UpdateAnimBlendLevel1/2/3 + AdvanceFrame 推进并写 AnimBlendResult;随后每帧(含渲染帧)渲染数据打包:变换组合(渲染器 Offset × FVisualize.Transform)、mesh tilt、物理枢轴、位压缩编码(EncodeFrames01 / EncodeFrame2AndLerps / EncodeDynamicParams0 / EncodeStatusEffects / EncodeAnimTracksA/B)、TextPop 收集、槽位写入(UniqueIDArray = MakeRenderIdentityToken)、parent+relative 或旧模型变换写入;④ 注册(仅模拟帧,单线程):Merge() 后按预提取 UID 键确定性排序;渲染器不存在时 LoadSynchronous + SpawnActor 创建;找空槽或 Add 扩容,写槽位绑定回 FVisualizing,初始化插值状态(首帧角速度增量≈0),置 Rendering 旗标;⑤ GC:空闲批次按 IdleRemoveCountdown 销毁 Niagara 组件并移除,渲染器无批次则 Destroy();⑥ Niagara 推送(并行):各数组(含 User.LogicTickTime = 引擎时间,供 GPU 计算 Elapsed);⑦ NDC TextPop(串行):跨批次聚合经 FMassTextPopWriter 写数据通道并置 EnableTextPop。

Per-tick entry. Resolves MB / MA / MS (returns early if missing); renders only on ESubFrame::Subtick3. Flow: ① slot-state reset (parallel): FreeSlotArray / IsHiddenArray / UniqueIDArray (identity tokens — GPU snaps any slot whose token changes); ② slot cooldown (sim tick only): recently-freed slots stay locked for PoollingCoolDown so the GPU sees an IsHidden gap; ③ per-entity update (parallel): on sim ticks — render toggle (FVisualize.bEnable ↔ NotRendering / Rendering flags), Montage end fallback (non-looping montage finished → back to PreviousAnimState), LOD selection (camera distance → screen size ScalingRadius / Distance × ProjectionFactor, pick the highest matching of five FLODData tiers, fall back to the smallest-ScreenSize tier; Actor ↔ Particle representation switching via MS.ActorSpawnRequestQueue / ActorRecycleQueue), anim flag cleanup (DeathAnim/AppearAnim/AttackAnim/HitAnim synchronized with their states), anim state decision (PauseAnimChange / Montage / Dying / Appearing / Attacking / Falling (delayed) / BeingHit / Move speed threshold / Idle; Idle/Move normalized to BS_IdleMove blend), state-change events (OnAnimStateChangeQueue, with AnimData/PlayRate/progress), attack-speed slow (max slow strength over SlowCausers when Defence.bCanSlowATKSpeed), reverse frame-extrap suppression (with bMoveCanReverse, hold raw frames 0.25s after a direction flip), three-layer UpdateAnimBlendLevel1/2/3 + AdvanceFrame writing AnimBlendResult; then every frame (render frames included) render data packing: transform composition (renderer Offset × FVisualize.Transform), mesh tilt, physics pivot, bit-packed encoding (EncodeFrames01 / EncodeFrame2AndLerps / EncodeDynamicParams0 / EncodeStatusEffects / EncodeAnimTracksA/B), TextPop collection, slot writes (UniqueIDArray = MakeRenderIdentityToken), parent+relative or old-model transform writes; ④ registration (sim tick only, single-threaded): after Merge(), deterministic sort by pre-extracted UID keys; create the renderer via LoadSynchronous + SpawnActor when missing; find a free slot or Add to grow, write the slot binding back to FVisualizing, initialize interp state (first-frame angvel delta ≈ 0), set the Rendering flag; ⑤ GC: idle batches count down IdleRemoveCountdown, destroy the Niagara component and remove; destroy renderers with no batches; ⑥ Niagara push (parallel): all arrays (plus User.LogicTickTime = engine time for GPU Elapsed computation); ⑦ NDC TextPop (serial): cross-batch aggregation via FMassTextPopWriter and the EnableTextPop variable.

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

无返回值。副作用:写 FVisualizing / FAnimating / FEntityFlagFragment / FScaling 等 fragment;向 MS.ActorSpawnRequestQueue / ActorRecycleQueue、MB.OnAnimStateChangeQueue、渲染批次数组、Niagara 组件与 NDC_TextPop 数据通道写入;注册/销毁渲染器与批次。

No return value. Side effects: writes FVisualizing / FAnimating / FEntityFlagFragment / FScaling etc.; writes to MS.ActorSpawnRequestQueue / ActorRecycleQueue, MB.OnAnimStateChangeQueue, render-batch arrays, Niagara components, and the NDC_TextPop data channel; spawns/destroys renderers and batches.

AddRenderBatch int32 (private)

在渲染器上新建渲染批次(现有批次满时):递增 NextRenderBatchId,Reserve(RenderBatchSize),经 SpawnSystemAtLocation 生成 Niagara 系统(设 AgentMesh 变量与投影),然后自动检测 NS 暴露的 User.* 数组变量(Position/Style/Velocity/AngVel/InterpParams/AnimTracksA/B/UniqueID/RelLoc/RelRot/RelScale/MeshIndex),置对应 bUse* 标志。bNewPredictionModel = 暴露任一 Rel* 数组。

Creates a new render batch on the renderer (when existing ones are full): bumps NextRenderBatchId, Reserve(RenderBatchSize), spawns the Niagara system via SpawnSystemAtLocation (sets the AgentMesh variable and cast shadow), then auto-detects which User.* array variables the NS exposes (Position/Style/Velocity/AngVel/InterpParams/AnimTracksA/B/UniqueID/RelLoc/RelRot/RelScale/MeshIndex), setting the corresponding bUse* flags. bNewPredictionModel = any Rel* array exposed.

Input
参数 Param类型 Type说明 Description
RendererActorAMassBattleAgentRenderer*目标渲染器 actor,持有批次表与 Niagara 资产。Target renderer actor holding the batch map and Niagara asset.
Output

返回新批次 ID。副作用:批次表新增条目并生成 Niagara 系统。

Returns the new batch ID. Side effects: new batch entry created and a Niagara system spawned.

UpdateAnimBlendLevel1 void (private)

基础层(槽 0)动画更新:仅在状态变更时(bStateChanged)按 CurrentState 从对应动画槽取数据(GetAnimDataFromSlotIndex),计算 PlayRate = (帧数/SampleRate)/目标时长(目标时长:Appear/Hit/Attack/Death 各自按 bAnimAsDuration 取动画长度或配置时长;攻击再乘 AttackSpeedMultiplier),循环/非循环设置;Idle↔Move 同一动画时继承播放进度,否则从 IdleRandomStartFrame / MoveRandomStartFrame 起步。进入 Appearing / Dying 态时,当前帧按共享进度定位(CurrentFrame0 = Lerp(StartFrame0, EndFrame0, AppearProgress / DeathProgress))——两个进度由模拟侧处理器(Reaction/Behavior)在 Particle 与 Actor 两种表示下每 sim tick 推进,使表示切换中途的死亡/出场动画续播而非从第 0 帧重播。

Base layer (slot 0) anim update: on state change only (bStateChanged), fetches data per CurrentState from the matching anim slot (GetAnimDataFromSlotIndex), computes PlayRate = (frames/SampleRate)/target duration (target duration: Appear/Hit/Attack/Death each take anim length or config duration per bAnimAsDuration; attack also multiplies AttackSpeedMultiplier), sets looping; Idle↔Move sharing the same anim inherits play progress, otherwise starts from IdleRandomStartFrame / MoveRandomStartFrame. On entering Appearing / Dying, the current frame is positioned by the shared progress (CurrentFrame0 = Lerp(StartFrame0, EndFrame0, AppearProgress / DeathProgress)) — both progresses are advanced every sim tick by the sim-side processors (Reaction/Behavior) in BOTH the Particle and Actor representations, so a mid-death / mid-appear representation switch resumes instead of replaying from frame 0.

Input
参数 Param类型 Type说明 Description
State 等多参数层级状态、动画共享数据、运行时动画状态、当前状态、变更标志、DeltaTime、各行为配置与 AttackSpeedMultiplier,共享进度 DeathProgress / AppearProgress(0–1,见上),输出 bOutReset0。Level state, anim shared data, animating runtime, current state, change flags, DeltaTime, per-behavior configs, AttackSpeedMultiplier, and the shared progresses DeathProgress / AppearProgress (0–1, see above); outputs bOutReset0.
Output

无返回值。副作用:写 State 的 Index0/StartFrame0/EndFrame0/CurrentFrame0/PlayRate0/bLoop0 与 bOutReset0。

No return value. Side effects: writes State's Index0/StartFrame0/EndFrame0/CurrentFrame0/PlayRate0/bLoop0 and bOutReset0.

UpdateAnimBlendLevel2 void (private)

混合层(槽 0=Idle 常驻,槽 1 目标轨道,槽 2 过渡缓存)动画更新。槽 0 恒为 Idle;槽 1 目标 = 当前状态动画(蒙太奇类)或 Move(Idle/Move 混合);Lerp0 在蒙太奇时趋于 1、Idle/Move 时按有效速度(线速度 + 角速度×AngularSpeedBlendMultiplier)映射 BS_IdleMove 区间并插值;目标与当前不同轨时槽 2 缓存过渡、Lerp 归零后迁移;Idle/Move 同动画时以混合 alpha 作播放速率乘数。

Blend layer (slot 0 = permanent Idle, slot 1 = target track, slot 2 = transition cache) anim update. Slot 0 is always Idle; slot 1's target is the current-state anim (montage-like) or Move (Idle/Move blend); Lerp0 converges to 1 for montages, or maps the effective velocity (linear + angular × AngularSpeedBlendMultiplier) into the BS_IdleMove range and interpolates for Idle/Move; when the target track differs, slot 2 caches the transition and migrates after Lerp reaches ~0; Idle/Move sharing one anim uses the blend alpha as a playrate multiplier.

Input
参数 Param类型 Type说明 Description
State 等多参数同 Level1 并追加 FMoving、DeathProgress / AppearProgress(Dying/Appearing 目标轨道恢复帧定位)与 LinearSpeed(调用点实测线速度:本 tick 位移 / Δt,异常时回退 Moving.CurrentVelocity.Size2D();Idle/Move 混合的有效速度 = LinearSpeed + |角速度| × AngularSpeedBlendMultiplier);输出 bOutReset1 / bOutReset2。Same as Level1 plus FMoving, DeathProgress / AppearProgress (positioning the Dying/Appearing target-track resume frame), and LinearSpeed (measured speed at the call site: per-tick displacement / Δt, falling back to Moving.CurrentVelocity.Size2D() when implausible; the Idle/Move blend's effective velocity = LinearSpeed + |angular velocity| × AngularSpeedBlendMultiplier); outputs bOutReset1 / bOutReset2.
Output

无返回值。副作用:写 State 的槽 0/1/2 参数与 Lerp0(Lerp1 恒 0)。

No return value. Side effects: writes State slots 0/1/2 parameters and Lerp0 (Lerp1 always 0).

UpdateAnimBlendLevel3 void (private)

最高层:槽 2 承载 Montage(从 OtherAnimData 取数据,PlayRate = MontagePlayRate,循环按 bMontageLooping);非蒙太奇时按 Idle/Move 与蒙太奇权重计算 Lerp0 / Lerp1 目标并插值。

Top layer: slot 2 carries the Montage (data from OtherAnimData, PlayRate = MontagePlayRate, looping per bMontageLooping); otherwise computes Lerp0 / Lerp1 targets from Idle/Move and montage weights and interpolates.

Input
参数 Param类型 Type说明 Description
State 等多参数同 Level2(DeathProgress / AppearProgress / LinearSpeed 同途——Appearing/Dying 时槽 2 当前帧按共享进度定位,Idle/Move 权重用有效速度);输出 bOutReset0 / bOutReset1 / bOutReset2。Same as Level2 (DeathProgress / AppearProgress / LinearSpeed used the same way — the slot-2 current frame is positioned by the shared progress on Appearing/Dying, and Idle/Move weights use the effective velocity); outputs bOutReset0 / bOutReset1 / bOutReset2.
Output

无返回值。副作用:写 State 的槽参数与 Lerp 值。

No return value. Side effects: writes State slot parameters and Lerp values.

AdvanceFrame void (private)

单槽逐帧推进:按 PlayRate × DeltaTime × SampleRate 累计帧位置,循环动画回绕,非循环播完停在 EndFrame;支持 MoveDirectionMultiplier 反向与 bSkipAdvance 跳过。

Per-slot frame advancement: accumulates frame position by PlayRate × DeltaTime × SampleRate, wraps looping anims, clamps non-looping anims at EndFrame; supports MoveDirectionMultiplier reversal and bSkipAdvance skipping.

Input
参数 Param类型 Type说明 Description
State / SlotIndex / DeltaTime / SampleRate / Animation / MoveDirectionMultiplier / bSkipAdvance多参数层级状态、槽索引(0-2)、帧时间、采样率、动画共享数据、方向乘数、跳过标志。Level state, slot index (0-2), delta time, sample rate, anim shared data, direction multiplier, skip flag.
Output

无返回值。副作用:推进 State.CurrentFrame*。

No return value. Side effect: advances State.CurrentFrame*.

CalculatePlayRate static float

播放速率计算:PlayRate = (|EndFrame - StartFrame| / SampleRate) / TargetDuration,即自然时长与目标时长之比;目标时长非正时返回 1.0f。

Play-rate computation: PlayRate = (|EndFrame - StartFrame| / SampleRate) / TargetDuration — natural time over target time; returns 1.0f for non-positive target durations.

Input
参数 Param类型 Type说明 Description
StartFrame / EndFrame / TargetDuration / SampleRatefloat / float / float / int32起始/结束帧、目标时长(秒)、采样率(帧/秒)。Start/end frames, target duration (s), sample rate (frames/s).
Output

返回播放速率倍率。

Returns the play-rate multiplier.

GetAnimDataFromSlotIndex static FVector4f

按槽索引(0-4)读取 FAnimData 的五个动画条目之一;越界返回 (−1, 0, 0, 0)(空槽标记)。

Reads one of the five anim entries of FAnimData by slot index (0-4); out of range returns (−1, 0, 0, 0) (empty-slot marker).

Input
参数 Param类型 Type说明 Description
Dataconst FAnimData&五槽动画数据。Five-slot anim data.
SlotIndexint32槽索引(0-4)。Slot index (0-4).
Output

返回对应动画的 FVector4f(X=Index, Y=时长, Z=StartFrame, W=EndFrame);越界返回 (−1,0,0,0)。

Returns the anim FVector4f (X=Index, Y=duration, Z=StartFrame, W=EndFrame); (−1,0,0,0) out of range.

ShiftSlotsForState static void (private)

把层级状态的槽 FromSlot 全部字段(帧/速率/索引/循环/起止帧)复制到槽 ToSlot——状态迁移时的轨道搬运。

Copies all fields (frame/rate/index/loop/start-end) of slot FromSlot to slot ToSlot in a level state — track shuffling on state transitions.

Input
参数 Param类型 Type说明 Description
State / FromSlot / ToSlotFPerLevelAnimState& / int32 / int32目标层级状态与源/目标槽。Target level state and source/target slots.
Output

无返回值。副作用:槽字段被复制。

No return value. Side effect: slot fields copied.

成员变量 Members

FMassTextPopWriter struct (头文件公开)

通过 NDC 批量写入 TextPop 的自定义 Writer(FNDCWriterBase 派生)。缓冲指针:PositionBuffer / LocationBuffer / ParamsBuffer(Vector4) / SubTypeBuffer,LWC 标志自动检测;InitBuffers() 按名解析,AppendBatch 批量写入。

Custom writer for bulk TextPop access via NDC (derived from FNDCWriterBase). Buffer pointers: PositionBuffer / LocationBuffer / ParamsBuffer (Vector4) / SubTypeBuffer with auto-detected LWC flags; InitBuffers() resolves by name, AppendBatch writes in bulk.

EntityQuery / RegistrationQueue FMassEntityQuery / FParallelGatherer<FMassEntityHandle> (private)

EntityQuery 为主查询(见 ConfigureQueries);RegistrationQueue 收集需注册的实体句柄,单线程注册阶段 Merge + 排序 + 排空。

EntityQuery is the main query (see ConfigureQueries); RegistrationQueue gathers entities needing registration, merged/sorted/drained in the single-threaded registration phase.

管线角色 Pipeline Role

注册于 UMassBattleSubsystem 的 RenderProcessors 组(帧末排空之后),与 UMassBattleFxRenderProcessor 并列;只在 Subtick3 子帧渲染。FVisualizing 的 Target* 缓存与动画状态由模拟侧处理器(Behavior/Reaction/Move)驱动并进快照;Actor 表示的 spawn/recycle 经 UMassBattleAgentSubsystem 的队列。FTracingShared.PlayerCameraLocation(由 Trace 处理器写)驱动 LOD;渲染帧跳过时 Niagara 在 GPU 自插值。

Registered in UMassBattleSubsystem's RenderProcessors group (after the end-of-frame drain), alongside UMassBattleFxRenderProcessor; renders only on the Subtick3 sub-frame. FVisualizing Target* caches and anim state are driven by sim-side processors (Behavior/Reaction/Move) and snapshot-restored; Actor representation spawn/recycle goes through UMassBattleAgentSubsystem queues. FTracingShared.PlayerCameraLocation (written by the Trace processor) drives LOD; Niagara self-interpolates on GPU on skipped frames.