MassBattleDebuggerCore.h
Source/MassBattleEditor/Public/MassBattleDebuggerCore.h
概述 Overview
只读 MassBattle 调试核心:实体/池统计、直连 fragment 的调试绘制(并行收集 + 游戏线程刷新)、按名反射解析的实体头顶数值叠加。全部为 FMassBattleDebuggerCore 的静态函数,无实例状态(绘制队列除外)。绝不写实体/池状态;从 Slate tick 在游戏线程运行——此时 world tick 未运行,Mass 数据结构稳定,与 processor 并行 chunk 读取同级安全。
Read-only MassBattle debugging core: entity/pool stats, direct fragment-based debug drawing (parallel gather + game-thread flush), and on-entity value text overlays resolved by name. Everything is a static function of FMassBattleDebuggerCore; no instance state (apart from the draw queues). It never writes entity/pool state and runs on the game thread from Slate tick — the world tick is not running then, Mass data is structurally stable, the same read-safety class as processor parallel chunk walks.
调试器直接从 fragment 读取并绘制,绝不经过 processor;绘制设置(FMBDebugDrawSettings)刻意独立于 dataasset 驱动的 FAgentDebug / bDrawDebugShape 开关——工具自有词汇表,互不干扰。绘制走「ParallelFor 收集 → 合并 → 确定性排序 → 按类别去重 UID 截断 → DrawDebug*(Duration=0)」管线,每编辑器帧由面板重绘。
The debugger draws from fragments directly, never via processors; its draw settings (FMBDebugDrawSettings) are intentionally independent of the dataasset-driven FAgentDebug / bDrawDebugShape toggles — a tool-owned vocabulary that does not interfere with them. Drawing goes through a "parallel gather → merge → deterministic sort → per-category distinct-UID cull → DrawDebug* (Duration=0)" pipeline, redrawn every editor frame by the panel.
EMBDebugCategory enum class
调试器统计面板跟踪的实体类别。普通实体类别(Agent~Debuff)对应各自的 tag 查询;宿主(host)类别对应 EHostEntityType,其中 FxCPUHost 是 Fx 宿主中带 FCpuInterpTag 的子型。COUNT 为类别计数,不作为类别使用。显示名见 GetCategoryDisplayName。
Entity categories tracked by the debugger stats panel. Plain entity categories (Agent through Debuff) map to their respective tag queries; host categories map to EHostEntityType, where FxCPUHost is the FCpuInterpTag-carrying subtype of Fx hosts. COUNT is the category count, not a category itself. Display names come from GetCategoryDisplayName.
| 值 Value | 显示名 Display | 说明 Description |
|---|---|---|
Agent | Agent | 战斗单位实体。Combat agent entities. |
Projectile | Projectile | 弹丸实体。Projectile entities. |
Loot | Loot | 战利品实体。Loot entities. |
FxEntity | FxEntity | 批量特效实体。Batched FX entities. |
Obstacle | Obstacle | 障碍实体(不进入池化生命周期,全部计为活跃)。Obstacle entities (never in the pooled lifecycle; all reported active). |
Debuff | Debuff | debuff 实体(同上,全部计为活跃)。Debuff entities (likewise all reported active). |
ActorHost | Actor Host | Actor 宿主。Actor hosts. |
FxHost | Fx Host | 特效宿主(GPU 插值)。FX hosts (GPU interpolation). |
FxCPUHost | Fx Host (CPU) | 特效宿主中带 FCpuInterpTag 的 CPU 子型。CPU subtype of Fx hosts carrying FCpuInterpTag. |
SoundHost | Sound Host | 音效宿主。Sound hosts. |
ProjectileHost | Projectile Host | 弹丸宿主。Projectile hosts. |
AgentHost | Agent Host | Agent 宿主(持有实体而非 UObject)。Agent hosts (hold entities, not UObjects). |
LootHost | Loot Host | 战利品宿主。Loot hosts. |
COUNT | — | 类别计数(数组定长用)。Category count (for array sizing). |
EMBDebugShape enum class
绘制管线刷新的形状类型——每种一一对应一次 DrawDebug* 调用。Sector 例外地拆为「弧线 + 两条边线」(引擎的 UMassBattleSubsystem::DrawDebugSector 是 private,这里自绘等价形状:水平面、偏航扫掠)。
Shape kinds flushed by the draw pipeline — each maps 1:1 to a DrawDebug* call, with Sector as the exception: it is drawn as an arc plus two edge lines (the engine-side UMassBattleSubsystem::DrawDebugSector is private, so an equivalent shape is drawn manually: horizontal plane, yaw sweep).
| 值 Value | 说明 Description |
|---|---|
Sphere | 球(DrawDebugSphere,12 段)。Sphere (DrawDebugSphere, 12 segments). |
Line | 线段(DrawDebugLine)。Line (DrawDebugLine). |
Arrow | 方向箭头(DrawDebugDirectionalArrow)。Directional arrow (DrawDebugDirectionalArrow). |
Circle | 圆(DrawDebugCircle,48 段)。Circle (DrawDebugCircle, 48 segments). |
Capsule | 胶囊(DrawDebugCapsule;flush 时高度折半并做 ≥0.01 防闪烁钳制)。Capsule (DrawDebugCapsule; height halved at flush with a ≥0.01 anti-flicker clamp). |
Sector | 扇形(DrawDebugCircleArc + 两条边线)。Sector (DrawDebugCircleArc + two edge lines). |
String | 文本(DrawDebugString)。Text (DrawDebugString). |
结构体 Structs
单一 gatherer 的变体绘制项:Shape 判别用哪个载荷,七种形状的配置(Sphere/Line/Arrow/Circle/Capsule/Sector/String)并排存放。之所以用「单一变体队列」而非多个类型化 gatherer:FParallelGatherer 的 TLS 缓存每线程只记住一个缓冲区,若在逐实体 worker 循环内交替使用多个类型化 gatherer,每次调用都会申领新槽并耗尽 MaxSlots=64(check 失败)——单一变体队列 = 每线程每帧一槽。
Single-gatherer variant draw item: Shape discriminates which payload is used; the seven shape configs (Sphere/Line/Arrow/Circle/Capsule/Sector/String) sit side by side. The reason for one variant queue instead of several typed gatherers: an FParallelGatherer's TLS cache holds ONE buffer per thread, so alternating multiple typed gatherers inside a per-entity worker loop would claim a new slot on every call and exhaust MaxSlots=64 (a check failure) — one variant queue = one slot per thread per frame.
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
Shape | EMBDebugShape | Sphere | 形状判别字段。Shape discriminator. |
SortKey | int32 | 0 | 排序键 = FDeterminism.UniqueID(缺失时退化为句柄 Index)——刷新时按它稳定排序,保证确定性刷新顺序。Sort key = FDeterminism.UniqueID (falls back to the handle index) — the flush stable-sorts by it for a deterministic flush order. |
Cat | uint8 | 0 | EMBDebugCategory 值——刷新时按类别做 MaxCount 预算。EMBDebugCategory value — drives the per-category MaxCount budget at flush. |
Sphere / Line / Arrow / Circle / Capsule / Sector / String | FDebugSphereConfig 等(引擎类型) | — | 七种形状各自的绘制配置载荷(位置/半径/颜色/时长等);仅 Shape 指向的那份有效。注意刷新时统一取全局 LineThickness,逐项线宽刻意被忽略。Per-shape draw payload (location/radius/color/duration etc.); only the one selected by Shape is meaningful. Note the flush uses the global LineThickness; per-item thickness is ignored on purpose. |
实体/池统计表中的一行。INDEX_NONE 表示该行不显示此列(面板渲染为「—」)。
One stats row in the entity/pool tables. INDEX_NONE marks a column as hidden for that row (the panel renders it as "—").
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
Key | FName | — | 行键(如 "Agent"、"Host.Fx"、"AgentState.Attacking"、"AudioComponent"),池流转按它拼接。Row key (e.g. "Agent", "Host.Fx", "AgentState.Attacking", "AudioComponent"); pool churn is spliced by key. |
DisplayName | FText | — | 本地化显示名(来自 GetCategoryDisplayName 或拼好的状态名)。Localized display name (from GetCategoryDisplayName or a composed state name). |
Total | int32 | 0 | tag 查询数(活跃 + 池内——池内实体保留 tag)。Tag query count (active + pooled — pooled entities keep their tags). |
Active | int32 | 0 | 实体行 = Activated 标志置位数;宿主行 = !bIsPooled 计数。Entity rows: count with the Activated flag set; host rows: count of !bIsPooled. |
Pooled | int32 | 0 | 池内休眠数(Total − Active)。Dormant-in-pool count (Total − Active). |
HostedObjects | int32 | INDEX_NONE | 宿主行专用:当前持有的有效 UObject 数;实体行为隐藏。Host rows only: count of valid held UObjects; hidden on entity rows. |
PoolSize | int32 | INDEX_NONE | 预留的「当前池内条目数」列。CollectStats 刻意不填:池内休眠实体保留 tag,Pooled 列本身就是池大小,再填会同一数字显示两遍。Reserved "current dormant entries" column. CollectStats deliberately leaves it unset: dormant pooled entities keep tags, so the Pooled column already IS the pool size — filling this would show the same number twice. |
FromPool | int32 | INDEX_NONE | 本 tick 池命中数(来自池状态查询,按 Key 拼接)。This-tick pool hits (from the pool-state query, spliced by Key). |
Fresh | int32 | INDEX_NONE | 本 tick 新建数。This-tick fresh builds. |
Note | FString | 空 | 自由附加文本(子系统计数、提示等);非空时面板追加一列。Free-form extra text (subsystem counters, hints); the panel appends a column when non-empty. |
工具自有的绘制设置——刻意独立于 dataasset 驱动的 FAgentDebug / bDrawDebugShape 开关。Agent 形状复刻 FAgentDebug 的词汇表但全部从 fragment 直接派生;弹丸/战利品形状集则是模拟侧 bDrawDebugShape 从未具备的成熟集(拾取半径等对玩法关键的形状模拟从不画)。
Tool-owned draw settings — intentionally independent of the dataasset-driven FAgentDebug / bDrawDebugShape toggles. The agent shapes mirror the FAgentDebug vocabulary but are all derived directly from fragments; the projectile/loot shape sets are mature sets the sim's bDrawDebugShape never had (gameplay-critical shapes like the pickup radius are never drawn by the sim).
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
bEnable | bool | false | 绘制总开关。Master draw switch. |
bAgentCollider | bool | true | 碰撞胶囊/球,红色(休眠银灰、池内深灰)。Collider capsule/sphere, red (silver when sleeping, dark gray when pooled). |
bAgentPBDInflated | bool | false | PBD 膨胀胶囊(FPhysicsShared.ColliderMult 放大),青色;球冠同样用膨胀半径。PBD-inflated capsule (scaled by FPhysicsShared.ColliderMult), cyan; caps use the inflated radius too. |
bAgentOrientation | bool | true | 前/右/上朝向三箭头(红/绿/蓝)。Forward/right/up orientation arrows (red/green/blue). |
bAgentGather | bool | false | 收集半径双圆(绿色,含 GatherHeight 上移的第二圈)+ 到当前目标的连线(青色)。Gather radius circles (green, second circle lifted by GatherHeight) + links to current targets (cyan). |
bAgentTrace | bool | false | 索敌扇形 + 目标连线/标记(目标丢失时画最后已知位置的暗色球)。Trace sector + target link/marker (a dim sphere at the last known location when the target is lost). |
bAgentMove | bool | false | 期望速度(黄)/当前速度(白)箭头。Desired (yellow) / current (white) velocity arrows. |
bAgentAvoidance | bool | false | 避障半径圆(紫色)。Avoidance radius circle (purple). |
bAgentLODColor | bool | false | 头顶 LOD 标记球(读 FVisualizing.CurrentLOD,五级配色)。LOD marker sphere above the head (reads FVisualizing.CurrentLOD, 5-level palette). |
bAgentUniqueID | bool | false | UniqueID 文本标签("A#UID")。UniqueID text label ("A#UID"). |
bProjRadius | bool | true | 弹丸碰撞半径球。Projectile collision radius sphere. |
bProjVelocityArrow | bool | true | 航向箭头——按移动类型(弹道/追踪/插值)取各自的速度方向与大小。Heading arrow — direction and magnitude taken from the per-move-type fragment (ballistic/tracking/interped). |
bProjTrajectory | bool | false | 起点→终点弹道线(青色)。From→To trajectory line (cyan). |
bProjTarget | bool | false | 目标实体标记(橙色球);无有效目标时画终点标记。Target entity marker (orange sphere); falls back to an endpoint marker with no valid target. |
bProjStateText | bool | false | UID + 状态文本(池内时附 "pool(剩余秒)")。UID + state text (pooled entities append "pool(countdown seconds)"). |
bLootPickupRadius | bool | true | 拾取半径球,绿色(拾取半径对玩法关键,模拟侧从不画)。Pickup radius sphere, green (gameplay-critical; never drawn by the sim). |
bLootCollisionRadius | bool | false | 碰撞半径球,橙色。Collision radius sphere, orange. |
bLootStateText | bool | false | 状态色文本(状态配色镜像 loot processor:Spawning 黄 / Ready 绿 / BeingCollected 青 / Collected 蓝 / Expired 红)。State-colored text (state palette mirrors the loot processor: Spawning yellow / Ready green / BeingCollected cyan / Collected blue / Expired red). |
bLootCollectorLink | bool | false | 到收集者实体的连线(青色)。Line to the collector entity (cyan). |
bLootTrajectory | bool | false | 生成/收集弹道线(From→To)。Spawn/gather trajectory line (From→To). |
MaxCountPerCategory | int32 | 200 | 每类别实体数上限;0 = 不限。刷新时排序后按去重 UID 截断——超出预算的实体丢弃其全部形状。Per-category entity budget; 0 = unlimited. Rank cull after sort on distinct UIDs at flush — entities beyond the budget drop ALL their shapes. |
MaxDrawDistance | float | 0 | 距离剔除半径(cm);0 = 不限。对照 UMassBattleSubsystem 缓存的调试相机位置(与 processor 入队时语义一致)。Distance-cull radius (cm); 0 = unlimited. Compared against the debug camera location cached by UMassBattleSubsystem (same semantics as processor enqueue time). |
LineThickness | float | 1.f | 所有绘制形状的统一线宽——一个旋钮等比控制全部形状(逐项线宽刻意被忽略)。Global thickness for every drawn shape — one knob scales everything uniformly (per-item values ignored on purpose). |
bDrawPooledDimmed | bool | true | 池内(Activated 已清)实体以暗色绘制;关闭则完全跳过。Draw pooled (Activated-cleared) entities dimmed; off skips them entirely. |
一条实体头顶数值叠加:按名反射解析 FragmentName.PropertyName(在已注册 fragment 集上),把实时值用 DrawDebugString 画在每个匹配实体的世界位置上。
One on-entity value overlay: resolves FragmentName.PropertyName by reflection over the registered fragment set and renders the live value as DrawDebugString text at each matching entity's world location.
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
FragmentName | FName | — | fragment 反射名,无 F 前缀("Health"、"LootParams" 等);解析大小写不敏感且前缀可选。Script-struct name without the F prefix ("Health", "LootParams", ...); resolution is case-insensitive with an optional prefix. |
PropertyName | FName | — | 该 fragment 上的属性名(经 TFieldRange<FProperty> 枚举)。Property on that fragment (enumerated via TFieldRange<FProperty>). |
Category | EMBDebugCategory | Agent | 限定叠加作用的实体类别(决定用哪个 tag 查询取实体)。Entity category the overlay applies to (decides which tag query fetches the entities). |
叠加过滤:距离对照缓存的调试相机、UID 白名单、按类别数量上限。
Overlay filters: distance vs the cached debug camera, a UID whitelist, and a per-category max count.
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
bEnable | bool | false | 叠加总开关。Master overlay switch. |
MaxCount | int32 | 100 | 每类别实体数上限;0 = 不限。排序后按去重 UID 截断。Per-category entity budget; 0 = unlimited. Rank cull after sort on distinct UIDs. |
MaxDist | float | 0 | 距离上限(cm);0 = 不限(相机缓存有效时才启用)。Distance limit (cm); 0 = unlimited (applied only when the camera cache is valid). |
LineStepScale | float | 1.f | 行距倍率:基准行距 = 相机距离 × 0.015(钳制 [2.5, 150]cm;相机无效时固定 7.5cm),乘以本值。Row spacing multiplier on the base step (camera distance × 0.015, clamped to [2.5, 150] cm; fixed 7.5 cm with no valid camera). |
UidFilter | TSet<int32> | 空 | UID 白名单;空 = 全部实体。UID whitelist; empty = all entities. |
公开方法 Public Methods
枚举全部活跃游戏世界:遍历 GEngine->GetWorldContexts(),收集 WorldType 为 PIE 或 Game 的有效世界(AddUnique 去重)。编辑器世界、预览世界不在其列;未运行 PIE/游戏时输出为空——面板据此显示 "no game world — start PIE"。
Enumerates all live game worlds: walks GEngine->GetWorldContexts() and collects valid worlds whose WorldType is PIE or Game (deduplicated via AddUnique). Editor and preview worlds are excluded; the output is empty when PIE/game is not running — the panel then shows "no game world — start PIE".
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
OutWorlds | TArray<TWeakObjectPtr<UWorld>>& | 输出数组,进入前先 Reset。Output array; reset before filling. |
Output
无返回值。副作用:仅写输出数组;GEngine 为空时直接清空返回。
No return value. Side effect: writes the output array only; returns empty immediately when GEngine is null.
把全部统计行快照进一张表,按 UI 频率调用(内部遍历 EntityManager,不要逐帧调用)。流程:① 普通实体类别——各类别一次 tag 查询得 Total;Agent 额外在同一次并行遍历里直接读 FEntityFlagFragment 做完整状态标志直方图(11 个固定状态行:Appearing/Sleeping/Patrolling/Attacking/Chasing/Approaching/BeingHit/Falling/BeingPushed/Launching/Dying),比子系统计数器更全的 ground truth;Obstacle/Debuff 从不进入 Activated/回收生命周期,全部计为活跃并跳过标志普查。② 宿主遍历——单次 FHostControllerTag 扫描,按 config fragment 分型到 7 行(Actor/Fx/FxCPU/Sound/Projectile/Agent/Loot;Fx 与 FxCPU 经 FCpuInterpTag 区分),统计持有 UObject 数并按 bIsPooled 拆分。③ 池流转拼接——经 UMassBattleFuncLib::GetPoolStates 把每 tick 的 FromPool/Fresh 拼进对应行;池大小刻意不拼(Pooled 列即池大小);音频组件是 UObject 池,单独成行,活跃持有数来自 Sound 宿主遍历。
Snapshots all stats rows into one table; called at UI cadence only (it walks the EntityManager — do not call per frame). Flow: ① plain entity categories — one tag query per category for Total; for Agents, the same parallel pass reads FEntityFlagFragment directly to build a full state-flag histogram (11 fixed state rows: Appearing/Sleeping/Patrolling/Attacking/Chasing/Approaching/BeingHit/Falling/BeingPushed/Launching/Dying) — ground truth richer than the subsystem's processor-updated counters; Obstacles/Debuffs never enter the Activated/recycle lifecycle, so all are reported active and the flag census is skipped. ② host walk — a single FHostControllerTag pass dispatches by config fragment into 7 rows (Actor/Fx/FxCPU/Sound/Projectile/Agent/Loot; Fx vs FxCPU via FCpuInterpTag), tallying held UObjects and splitting by bIsPooled. ③ pool churn splice — per-tick FromPool/Fresh from UMassBattleFuncLib::GetPoolStates spliced into the matching rows; pool sizes are intentionally NOT spliced (the Pooled column already equals the pool size); audio components are a UObject pool and get their own row, with the active-held count from the sound host walk.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 目标游戏世界;无效或 MassAPI 子系统取不到时直接返回。Target game world; returns immediately when invalid or the MassAPI subsystem is unavailable. |
OutRows | TArray<FMBDebuggerRow>& | 输出行数组,进入前先 Reset。Output row array; reset before filling. |
Output
无返回值。副作用:仅写输出数组——对实体/池状态零写入。
No return value. Side effect: writes the output array only — zero writes to entity/pool state.
按设置直接从 fragment 绘制全部启用的 pass(Duration=0,每编辑器帧由面板重绘)。流程:① 对 Agent / Projectile / Loot 三类各取 tag 句柄,仅当对应形状组有开关打开才启动该 pass;② ParallelFor 逐实体收集——无 FLocating 跳过、超距剔除(对照子系统缓存的调试相机)、未激活实体按 bDrawPooledDimmed 决定暗色绘制或跳过;条目 SortKey = FDeterminism.UniqueID(退化句柄 Index)写入全局唯一绘制队列 GDrawQueue;③ 游戏线程刷新——Merge → 按 SortKey 稳定排序 → 按类别去重 UID 的 MaxCount 截断(镜像 ProcessDrawDebugQueues 的 rank 语义)→ 直接 DrawDebug*,全部形状统一用全局 LineThickness。
Draws every enabled pass directly from fragments per the settings (Duration=0, redrawn every editor frame by the panel). Flow: ① fetch tag handles for Agent / Projectile / Loot, launching a pass only when at least one of its shape toggles is on; ② parallel per-entity gather — skip without FLocating, distance-cull against the subsystem's cached debug camera, and honor bDrawPooledDimmed for inactive entities; items keyed by SortKey = FDeterminism.UniqueID (falling back to the handle index) go into the single global draw queue GDrawQueue; ③ game-thread flush — merge → stable sort by SortKey → per-category distinct-UID MaxCount cull (mirroring the rank semantics of ProcessDrawDebugQueues) → direct DrawDebug* calls, all shapes using the global LineThickness.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 目标世界;无效或 bEnable 关闭时直接返回。Target world; returns immediately when invalid or bEnable is off. |
Settings | const FMBDebugDrawSettings& | 绘制设置(见结构体一节)。Draw settings (see the struct section). |
Output
无返回值。副作用:向引擎调试绘制系统发出一批 Duration=0 的形状(单帧可见,靠每帧重绘维持);重置并重填静态绘制队列 GDrawQueue。
No return value. Side effects: emits a batch of Duration=0 shapes into the engine debug-draw system (one-frame lifetime, sustained by per-frame redraw); resets and refills the static draw queue GDrawQueue.
「按名 watch」注册表查询(Niagara 调试器式):GetWatchableFragmentNames 列出全部已注册可 watch 的 fragment 反射名(惰性一次性注册表,精选自携带有效调试状态的插件 fragment——FMainType 到 FPhysicsShared/FLODShared 共约 60 项,含普通/共享 fragment、弹丸/战利品/宿主/障碍/debuff 各型);GetWatchablePropertyNames 先按名解析 fragment(大小写不敏感、F 前缀可选),再经 TFieldRange<FProperty> 列出其全部属性名。解析失败输出为空。
Name-registry queries for Niagara-style watching: GetWatchableFragmentNames lists every registered watchable fragment name (a lazy one-time registry curated from plugin fragments carrying meaningful debug state — roughly 60 entries from FMainType through FPhysicsShared/FLODShared, covering plain/shared fragments, projectile/loot/host/obstacle/debuff variants); GetWatchablePropertyNames resolves the fragment by name (case-insensitive, optional F prefix), then lists all its property names via TFieldRange<FProperty>. Unresolvable names yield an empty output.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
OutNames | TArray<FName>& | 输出名列表(GetWatchableFragmentNames)。Output name list (GetWatchableFragmentNames). |
FragmentName | FName | 待解析的 fragment 名(GetWatchablePropertyNames;可带可不带 F 前缀)。Fragment name to resolve (GetWatchablePropertyNames; F prefix optional). |
Output
无返回值。副作用:首次调用惰性构建静态注册表。
No return value. Side effect: the first call lazily builds the static registry.
按实体类别输出精选 fragment 组合(镜像各类别的生成模板),驱动叠加行的类别过滤 fragment 选择器。仅已注册名进入 UI;组合漂移优雅降级——列了但该实体没有的 fragment 只是不绘制。Agent 24 项、Projectile/Loot 各 13 项、宿主各类 4 项(Locating/Determinism/HostHierarchy/对应 Config_Final)等。
Curated fragment composition per entity category (mirroring the build templates), driving the overlay row's category-filtered fragment picker. Only registered names reach the UI; composition drift degrades gracefully — a listed-but-missing fragment simply draws nothing on those entities. Agent lists 24 entries, Projectile/Loot 13 each, host categories 4 each (Locating/Determinism/HostHierarchy/the matching Config_Final), etc.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Cat | EMBDebugCategory | 目标类别。Target category. |
OutNames | TArray<FName>& | 输出名列表。Output name list. |
Output
无返回值。副作用:仅写输出数组。
No return value. Side effect: writes the output array only.
把每条叠加的实时值画到对应实体头顶(Duration=0,每编辑器帧重绘)。逐叠加:按 Category 取实体句柄(宿主类别统一走 FHostControllerTag);ParallelFor 逐实体——锚点取自身 FLocating,缺失时回退到 FHostHierarchy.AttachmentEntity 的位置(debuff 类子实体无变换碎片,挂在目标上);距离/UID 白名单过滤;值部分经反射读取(bool → "true"/"false",枚举 → 值名,其余 ExportTextItem 文本导出,空结果记 "?"),fragment/属性未解析时行降级为仅 UID 模式(新加未选择的行也能先看到实体 UID)。多行堆叠:第 i 行位于头部锚点沿堆叠方向向下偏移 i 个行距(相机有效 → 相机朝上的屏幕式堆叠 + 距离缩放行距;无效 → 世界向上 + 固定小行距,避免服务器/PIE 初期的垃圾相机位置把行距炸到地图尺度)。刷新与形状 pass 同语义:稳定排序 + 按类别去重 UID 的 MaxCount 截断。文本形如 #UID 值(黄色)。
Draws every overlay's live value as text on its entities (Duration=0, per-editor-frame). Per overlay: fetch entity handles by Category (all host categories share the FHostControllerTag query); per entity in parallel — the anchor is the entity's own FLocating, falling back to the FHostHierarchy.AttachmentEntity location (debuff-style child entities carry no transform fragment and live on their target); distance/UID-whitelist filters; the value part is read via reflection (bool → "true"/"false", enum → value name, everything else text-exported via ExportTextItem, "?" when empty) — an unresolved fragment/property degrades the row to UID-only mode, so a freshly added row with nothing picked already shows entity UIDs. Multi-row stacking: row i sits i line steps BELOW the head anchor along the stack direction (valid camera → screen-up stacking with distance-scaled steps; invalid → world-up stacking with a fixed modest step, so the garbage camera location on server worlds / early PIE cannot blow the spacing to map scale). The flush uses the same semantics as the shape pass: stable sort + per-category distinct-UID MaxCount cull. Text looks like #UID value (yellow).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 目标世界;无效、bEnable 关闭或叠加为空时直接返回。Target world; returns immediately when invalid, bEnable is off, or the overlay list is empty. |
Settings | const FMBOverlaySettings& | 叠加过滤设置。Overlay filter settings. |
Overlays | const TArray<FMBOverlayEntry>& | 叠加行列表。List of overlay rows. |
Output
无返回值。副作用:发出一批 Duration=0 的 DrawDebugString;使用独立的函数级静态叠加队列(与形状队列分属两个 ParallelFor 波次)。
No return value. Side effects: emits Duration=0 DrawDebugString calls; uses a separate function-local static overlay queue (a different ParallelFor wave from the shape pass).
类别的本地化显示名(面板与叠加 UI 共用),如 "Agent"、"Fx Host (CPU)"。未知类别返回空文本。
Localized display name for a category (shared by the panel and overlay UI), e.g. "Agent", "Fx Host (CPU)". Returns empty text for unknown categories.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Cat | EMBDebugCategory | 目标类别。Target category. |
Output
返回 NSLOCTEXT 显示名;未知类别为 FText::GetEmpty()。
Returns the NSLOCTEXT name, or FText::GetEmpty() for unknown categories.
管线角色 Pipeline Role
本核心是编辑器侧调试工具链的数据层,在发布树中的唯一使用者是 SMassBattleDebuggerPanel(Slate 面板):面板 Tick(游戏线程,world tick 未运行)按节流间隔调用 CollectStats,每编辑器帧调用 DrawWorld / DrawTextOverlays;世界列表经 GetGameWorlds 刷新;叠加行的类别/fragment/属性三个下拉由 GetCategoryFragmentNames、GetWatchablePropertyNames 与 GetCategoryDisplayName 供给。数据访问全部只读:tag 查询经 UMassAPIFuncLib::GetMatchingEntities,fragment 读取经 UMassAPISubsystem 的 GetFragmentPtr / GetSharedFragmentPtr / HasFlag;距离剔除参照 UMassBattleSubsystem 缓存的调试相机位置;池流转经 UMassBattleFuncLib::GetPoolStates(宿主子系统 UMassBattleHostSubsystem 有效时)。绘制不经过任何 processor——与模拟自身的 bDrawDebugShape 路径完全独立。
This core is the data layer of the editor-side debugging toolchain; its sole consumer in the release tree is SMassBattleDebuggerPanel (the Slate panel): the panel's Tick (game thread, world tick not running) calls CollectStats at a throttled interval and DrawWorld / DrawTextOverlays every editor frame; the world list refreshes via GetGameWorlds; the overlay row's category/fragment/property pickers are fed by GetCategoryFragmentNames, GetWatchablePropertyNames and GetCategoryDisplayName. All data access is read-only: tag queries via UMassAPIFuncLib::GetMatchingEntities, fragment reads via UMassAPISubsystem's GetFragmentPtr / GetSharedFragmentPtr / HasFlag; distance culling references the debug camera location cached by UMassBattleSubsystem; pool churn via UMassBattleFuncLib::GetPoolStates (when the host subsystem UMassBattleHostSubsystem is valid). Drawing never goes through processors — fully independent of the sim's own bDrawDebugShape path.
补充说明 Notes
① 形状队列 GDrawQueue 是文件级静态单例,叠加队列则是 DrawTextOverlays 内的函数级静态——两个队列与线程的 TLS 配对开销为每帧两对,远低于 FParallelGatherer::MaxSlots = 64。② 全部绘制 Duration=0:单帧可见,靠面板每编辑器帧重绘维持,PIE 暂停时依然可见。③ Agent 状态直方图直接读 FEntityFlagFragment 的置位(无需逐标志查询),是比 processor 维护计数器更全的 ground truth。④ FMassBattleDebuggerCore 无构造逻辑、无成员变量,全部入口为 static。
① The shape queue GDrawQueue is a file-level static singleton, while the overlay queue is a function-local static inside DrawTextOverlays — two queue/thread TLS pairs per frame, well under FParallelGatherer::MaxSlots = 64. ② All drawing uses Duration=0: visible for one frame and sustained by the panel's per-editor-frame redraw, remaining visible even when PIE is paused. ③ The agent state histogram reads the set bits of FEntityFlagFragment directly (no per-flag queries) — ground truth richer than the processor-maintained counters. ④ FMassBattleDebuggerCore has no constructor logic and no member variables; every entry point is static.