MassBattle Docsv1.19.20

UMassBattleAgentReactionProcessor

UCLASS Processor

Source/MassBattle/Public/Processors/MassBattleAgentReactionProcessor.h

概述 Overview

合并的受击反应与死亡序列处理器。先执行 Hit 逻辑,随后若 agent 死亡/濒死立即执行 Death 逻辑。核心职责:① 伤害分配:把并行 gatherer(DmgGatherer,由 Behavior/Projectile/Debuff 并行写入)串行排序(确定性元组)后分发给各受害实体的 FHealth.DmgResults;② 受击处理:确定性合并(按施害者分组、升序浮点累加、发射方向平均)、公平洗牌(实体自身 RandomStream)、扣血、命中生成(Actor/Fx/Sound)、TextPop、HitGlow/HitJiggle/HitAnim 曲线驱动与冷却;③ 杂项:SubType/Team 标签交换、ControlMode → PlayerDriven 旗标同步、Return 回归触发、寿命到期/KillZ 死亡;④ 死亡序列:死亡生成(Loot/Actor/Fx/Sound)、死亡动画/溶解曲线、DespawnDelay 后销毁;⑤ Gather 认领仲裁:并行入队 FLootClaimRequest → 串行排序(战利品 UID → 距离 → CollectorUID,等距组用战利品自身 RandomStream 洗牌)决定赢家;⑥ 统计结算:StatsGatherer 按目标分组、升序累加 TotalDamage / TotalKills / TotalScore 并广播统计事件。

Merged hit-reaction and death-sequence processor. Runs Hit logic first, then immediately processes Death logic if the agent dies or is dying. Core responsibilities: ① damage distribution: serially sorts the parallel gatherer (DmgGatherer, written in parallel by Behavior/Projectile/Debuff) by a deterministic tuple and distributes results into each victim's FHealth.DmgResults; ② hit processing: deterministic merge (grouped by instigator, ascending float accumulation, launch-direction averaging), fair shuffle (entity's own RandomStream), health deduction, hit spawns (Actor/Fx/Sound), TextPop, HitGlow/HitJiggle/HitAnim curve driving with cooldowns; ③ misc: SubType/Team tag swapping, ControlMode → PlayerDriven flag sync, Return trigger, lifespan-expiry / KillZ death; ④ death sequence: death spawns (Loot/Actor/Fx/Sound), death anim / dissolve curves, destroy after DespawnDelay; ⑤ loot-claim arbitration: parallel FLootClaimRequest enqueue → serial sort (loot UID → distance → CollectorUID, equal-distance groups shuffled with the loot's own RandomStream) decides the winner; ⑥ stats settlement: StatsGatherer grouped per target, ascending accumulation of TotalDamage / TotalKills / TotalScore, and statistics events.

继承 Inheritance

UMassProcessor → UMassBattleAgentReactionProcessor

公开方法 Public Methods

UMassBattleAgentReactionProcessor 构造函数

构造函数。设置 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> + All<FCollider, FAgentController, FAgentDebug, FBehaving, FReturn>(MARO) + All<FLocating, FRotating, FScaling, FHealth, FBeingHit, FAttack, FDeath, FMoving, FAgentEvent, FEntityFlagFragment, FStatistics, FDeterminism, FHit, FHealthBar, FTextPop, FDying, FNavigating, FMove, FAnimating, FGather, FGathering, FSubType, FTeam, FAgentControlling, FReturning>(MARW) + All<FCurveShared, FAnimShared>(MARW)。

Initializes the entity query: All<FAgentTag> + All<FCollider, FAgentController, FAgentDebug, FBehaving, FReturn>(MARO) + All<FLocating, FRotating, FScaling, FHealth, FBeingHit, FAttack, FDeath, FMoving, FAgentEvent, FEntityFlagFragment, FStatistics, FDeterminism, FHit, FHealthBar, FTextPop, FDying, FNavigating, FMove, FAnimating, FGather, FGathering, FSubType, FTeam, FAgentControlling, FReturning>(MARW) + All<FCurveShared, FAnimShared>(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 / MBH / MA(缺失返回),只在 ESubFrame::Subtick1 执行。流程:Phase 0 伤害分配:DmgGatherer.Merge() → 确定性模式按 (受害 UID → InstigatorID → 施害 UID → DmgDealt) 排序(UID 键预提取,比较器 O(1))→ 逐条分发进 FHealth.DmgResults → Reset。并行遍历逐实体:杂项:SubType/Team 标签交换(DeferredContext)、Controller.ControlMode ↔ PlayerDriven 旗标同步、Statistics.TotalTime 累计、Return 回归触发(仅 Idle 且被推离 Home 时,InitDelay 后置 ReturningFlag;回归中卡住超时把当前位置设为新 Home)、寿命到期(Death.LifeSpan)与 KillZ 死亡;Phase 1 受击(BeingHit 旗标):冷却计时递减;本实体伤害列表确定性处理——按 DmgDealt 升序(InstigatorID 平局)排序 → 按施害者合并(浮点升序累加、发射方向取含 launch 命中的平均)→ 按 InstigatorID 排序 → Fisher-Yates 洗牌(实体自身 RandomStream,公平分配击杀归属);逐伤害:命中生成(共用 FSpawnFrame,含 RandSource)、CreditToEntity 链解析统计归属(循环上限 10)、扣血(Health.Current -= Min(DamageToTake, Current))、致死时初始化 FDying + FDyingTag + 死亡事件、统计入 StatsGatherer(伤害/击杀/分数)、TextPop 样式分级、血条自动隐藏计时;HitGlow(曲线)、HitJiggle(Scaling.JiggleMultiplier 曲线)、HitAnim(受击事件 tick 无条件选取动画槽——锁步驱动)各自按曲线/时长推进并清旗标;血条比例/透明度更新;Phase 2 死亡(Dying 旗标或 FDestroyingTag):Destroy 标签直接销毁;Death.bEnable 时初始化(禁飞行、禁用碰撞倒计时、死亡生成 Actor/Fx/Sound/Loot 批、DespawnDelay 起死亡动画/溶解曲线),Dying.Time 推进,到期 PendingDestroy + 销毁队列;Phase 3 采集:对 Gathering.CurrentTargets 逐目标——未被认领的战利品入队 FLootClaimRequest(含距离键),已归属他人/已收集的移除;Phase 1.5 认领仲裁(串行):LootClaimGatherer.Merge() → 按 (LootUID → DistSq → CollectorUID) 排序,每战利品取首个请求(等距组用战利品自身 RandomStream 洗牌决胜)串行写 FLootParamsRT.Collector(仅 Ready 状态的战利品可被认领);Phase 2 统计结算(串行):StatsGatherer.Merge() → 按目标分组、DamageDelta 升序累加 → 写 FStatistics 并广播统计事件。chunk 末更新 MB.HitAgentCount / DyingAgentCount 原子计数与四个事件队列。

Per-tick entry. Resolves MB / MBH / MA (returns early if missing), gated on ESubFrame::Subtick1. Flow: Phase 0 damage distribution: DmgGatherer.Merge() → in deterministic mode sort by (victim UID → InstigatorID → causer UID → DmgDealt; UID keys pre-extracted so the comparator is O(1)) → distribute each entry into FHealth.DmgResults → Reset. Parallel per-entity: misc: SubType/Team tag swapping (DeferredContext), Controller.ControlMode ↔ PlayerDriven flag sync, Statistics.TotalTime accumulation, Return trigger (only while Idle and pushed away from Home; sets ReturningFlag after InitDelay; a stuck timeout adopts the current location as the new Home), lifespan-expiry (Death.LifeSpan) and KillZ deaths; Phase 1 hit (BeingHit flag): cooldown timers; deterministic processing of the local damage list — sort by DmgDealt ascending (InstigatorID tie-break) → merge by instigator (ascending float accumulation, hit direction averaged over launch-bearing hits) → sort by InstigatorID → Fisher-Yates shuffle (entity's own RandomStream, fair kill attribution); per damage: hit spawns (shared FSpawnFrame including RandSource), CreditToEntity-chain resolution for stats attribution (loop cap 10), health deduction (Health.Current -= Min(DamageToTake, Current)), lethal hits initialize FDying + FDyingTag + a death event, stats into StatsGatherer (damage/kills/score), TextPop style tiers, health-bar auto-hide timer; HitGlow (curve), HitJiggle (Scaling.JiggleMultiplier curve), HitAnim (unconditional slot pick at the hit-event tick — lockstep-driven) each advance per curve/duration and clear their flags; health-bar ratio/opacity update; Phase 2 death (Dying flag or FDestroyingTag): destroy-tagged entities go straight to the destroy queue; when Death.bEnable, initialize (disable flying, collision-disable countdown, death Actor/Fx/Sound/Loot batches, DespawnDelay starting death anim / dissolve curves), advance Dying.Time, then PendingDestroy + destroy queue; Phase 3 gathering: per Gathering.CurrentTargets target — unclaimed loot enqueues a FLootClaimRequest (with the distance key), loot claimed by others / already collected is removed; Phase 1.5 claim arbitration (serial): LootClaimGatherer.Merge() → sort by (LootUID → DistSq → CollectorUID), the first request per loot wins (equal-distance groups shuffled with the loot's own RandomStream) and writes FLootParamsRT.Collector serially (only Ready-state loot is claimable); Phase 2 stats settlement (serial): StatsGatherer.Merge() → group per target, ascending DamageDelta accumulation → writes FStatistics and broadcasts stats events. At chunk end, updates the MB.HitAgentCount / DyingAgentCount atomic counters and the four event queues.

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

无返回值。副作用:写受害者的 FHealth / FBeingHit / FDying / FAnimating / FScaling / FHealthBar 等;向 MBH 的 spawn 批、MB 的 StatsGatherer / LootClaimGatherer / 事件队列 / 销毁队列 / TextPop / 调试队列写入;更新 MB.HitAgentCount / DyingAgentCount。

No return value. Side effects: writes victims' FHealth / FBeingHit / FDying / FAnimating / FScaling / FHealthBar etc.; writes to MBH spawn batches, MB's StatsGatherer / LootClaimGatherer / event queues / destroy queue / TextPop / debug queues; updates MB.HitAgentCount / DyingAgentCount.

成员变量 Members

FReactionScratchContext struct (头文件公开)

Reaction 处理器线程本地临时上下文(消除 BeingHit 路径上的每 Agent TMap/TArray 分配抖动):MergedByInstigator(按施害者确定性合并映射)、LaunchDirByInstigator(按施害者累积发射方向,FLaunchDirAccum 含 Sum/Count)、LocalHitEvents / LocalDeathEvents / LocalStatEvents。ResetPerChunk() 重置事件数组,ResetPerAgent() 重置两个映射表。

Thread-local scratch context for the Reaction processor (eliminates per-agent TMap/TArray allocation churn on the BeingHit path): MergedByInstigator (per-hit deterministic merge map), LaunchDirByInstigator (per-instigator launch-direction accumulation; FLaunchDirAccum holds Sum/Count), LocalHitEvents / LocalDeathEvents / LocalStatEvents. ResetPerChunk() resets event arrays; ResetPerAgent() resets the two maps.

管线角色 Pipeline Role

注册于 UMassBattleSubsystem 的 SimStages[2],与 Debuff 处理器同阶段、先于其后的 Loot 阶段:消费 DmgGatherer(由 Behavior/Projectile/Debuff 阶段并行写入的全部伤害),生成的死亡与收集请求让 SimStages[3] 的 LootMonoProcessor 同帧可见;认领仲裁串行写 FLootParamsRT.Collector 后,Loot 处理器本帧即见。只在 Subtick1 子帧运行。命中/死亡事件进 OnHitQueue / OnDeathQueue / OnStatisticsChangeQueue,统计结算写 FStatistics。

Registered in UMassBattleSubsystem's SimStages[2], same stage as the Debuff processor and before the Loot stage: consumes DmgGatherer (all damage written in parallel by the Behavior/Projectile/Debuff stages); the deaths and claim requests it produces are visible to SimStages[3]'s LootMonoProcessor the same frame; after serial arbitration writes FLootParamsRT.Collector, the Loot processor sees it this frame. Runs only on the Subtick1 sub-frame. Hit/death events go to OnHitQueue / OnDeathQueue / OnStatisticsChangeQueue; stats settlement writes FStatistics.