UMassBattleFormationAlgorithms
Source/MassBattle/Public/FuncLibs/MassBattleFormationAlgorithms.h
概述 Overview
阵型生成与槽位分配算法库(纯静态函数),由 MassBattleFuncLib 的 GenerateGridFormation / GenerateCircularFormation / GenerateTriangleFormation 蓝图节点调用。核心分配器 AssignPositionsFromData 是线程安全核心——不访问 ECS,只操作预捕获数据,可按飞行状态分区后每组在完整槽位列表上独立分配。两种分配模式:KeepFormation(纯刚体平移 + 可选绕质心旋转,目标经 ResolveTranslatedGoalsOnGround 贴地解析——绝不删点,每 agent 恰一个目标)与 ReformTheLine(晶格重整:稀疏混合候选拍卖算法 + 气泡压缩 + 跨阵型交换修复 + 链式位移半径修复,就近分配)。槽位晶格生成族(GenerateGridSlotPositions / GenerateTriangleSlotPositions / GenerateCircularSlotPositions + Append*Growth 生长补足)是纯数学、线程安全的单一数据源,同步 Impl 与异步 BPTask(MassBattleBPTaskGenerateFormation)共用;FitAgents 尺寸模式由目标槽位数推导晶格大小,槽位始终够用。IsFormationSlotEligible 在任何计数之前剔除陈旧选集幽灵(死亡/濒死/不可移动句柄)。配套:半径采样(ComputeAgentFormationRadius,碰撞体或避障椭圆两种来源)、地面/障碍物追踪验证与确定性随机偏移(ValidateAndOffsetPositions,随机种子由位置内容哈希派生)、大 Agent 槽位排除脚印族 EFormationFootprint(Box / Circle / Hexagon)、可视化(DrawFormationVisualization,经 UMassBattleSubsystem 的 LineBatch* MPSC 队列由中心排空,Shipping 可见)。
Formation generation and slot-assignment algorithm library (pure static functions), called by the GenerateGridFormation / GenerateCircularFormation / GenerateTriangleFormation Blueprint nodes in MassBattleFuncLib. The core assigner AssignPositionsFromData is a thread-safe core — no ECS access, operates on pre-captured data, and can partition agents by flying status, assigning each group independently over the full slot list. Two assignment modes: KeepFormation (pure rigid translation + optional rotation about the centroid, goals ground-resolved via ResolveTranslatedGoalsOnGround — no point is ever dropped, exactly one goal per agent) and ReformTheLine (an intentional lattice reshape: sparse hybrid-candidate auction + bubble compaction + cross-formation swap repair + chain-displacement radius repair, nearest-slot assignment). The slot-lattice generation family (GenerateGridSlotPositions / GenerateTriangleSlotPositions / GenerateCircularSlotPositions + Append*Growth trace-shortfall regrowth) is pure math, thread-safe, and the single source of truth shared by the sync Impls and the async BPTask (MassBattleBPTaskGenerateFormation); the FitAgents sizing mode derives the lattice size from the target slot count so slots always suffice. IsFormationSlotEligible filters stale-selection ghosts (dead / dying / immovable handles) before any count is taken. Supporting pieces: radius sampling (ComputeAgentFormationRadius, from the collider or the avoidance ellipse), ground/obstacle trace validation with deterministic random offset (ValidateAndOffsetPositions, seed derived from position-content hash), the large-agent slot-exclusion footprint family EFormationFootprint (Box / Circle / Hexagon), and visualization (DrawFormationVisualization, pushed through UMassBattleSubsystem's LineBatch* MPSC queues for central drain, visible in Shipping).
EFormationFootprint enum class
大 Agent 槽位排除测试的脚印族,跟随阵型族选用:网格 → Box,圆形 → Circle,三角 → Hexagon。由 AssignPositionsFromData(阻挡网格)与 ComputeBlockerExtraSlotCount(额外槽位需求)消费。
Blocker footprint family for the large-agent slot-exclusion test, chosen to follow the formation family: grid → Box, circular → Circle, triangle → Hexagon. Consumed by AssignPositionsFromData (blocker grid) and ComputeBlockerExtraSlotCount (extra slot demand).
| 值 Value | 说明 Description |
|---|---|
Box | 方形脚印(与晶格对齐),网格阵型使用。Square footprint (lattice-aligned), used by grid formations. |
Circle | 包围圆脚印,圆形阵型使用。Bounding-circle footprint, used by circular formations. |
Hexagon | 正六边形脚印(一条顶点沿阵型朝前),三角阵型使用。Regular-hexagon footprint (one vertex forward along the formation), used by triangle formations. |
公开方法 Public Methods
线程安全分配核心:无 ECS 访问,操作预捕获数据。先按飞行状态(AgentCanFly,缺失条目默认非飞行)把 agent 索引分成地面/飞行两组;若任一组为空走单组快速路径。双组路径下每组在完整槽位列表上独立调用 AssignPositionsSingleGroup 分配——飞行与非飞行组的 XY 结果可能重合,因运行时它们处于不同 Z 层。单组内部按 AssignmentMode 分派:KeepFormation 用「理想位置贪心(大半径优先)+ 阻挡网格 + 局部成对交换修复」;ReformTheLine 用「稀疏混合候选拍卖(KNear 局部 + KStrat 错位步长覆盖,保证全槽位可竞价)+ 气泡压缩(空位逐环向外冒)+ 跨阵型成对交换 + 链式位移半径修复」。确定性:排序键含 AgentUniqueIDs,候选与堆操作带确定性 tie-break。
Thread-safe assignment core: no ECS access, operates on pre-captured data. First partitions agent indices by flying status (AgentCanFly; missing entries default to non-flying) into ground/flying groups; either group empty takes the single-group fast path. On the two-group path each group runs AssignPositionsSingleGroup independently over the full slot list — flying and ground results may coincide in XY because they occupy different Z layers at runtime. Within a group the AssignmentMode dispatches: KeepFormation uses "ideal-position greedy (largest radius first) + blocker grid + localized pairwise swap repair"; ReformTheLine uses "sparse hybrid-candidate auction (KNear locality + KStrat stride-sampled coverage so every slot is biddable) + bubble compaction (holes ripple outward ring by ring) + cross-formation pairwise swap + chain-displacement radius repair". Determinism: sort keys include AgentUniqueIDs; candidates and heap operations carry deterministic tie-breaks.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
AgentLocations | const TArray<FVector>& | 各 agent 当前位置(用于 centroid 映射与拍卖成本)。Current agent locations (for centroid mapping and auction costs). |
AgentRadii | const TArray<float>& | 各 agent 阵型半径。Per-agent formation radii. |
AgentUniqueIDs | const TArray<int32>& | 各 agent 唯一 ID——确定性排序与拍卖分层偏移的种子。Per-agent unique IDs — deterministic sort keys and auction stratification offsets. |
AgentCanFly | const TArray<bool>& | 飞行标志(可为空 = 全部非飞行)。Flying flags (may be empty = all non-flying). |
FormationPositions | const TArray<FVector>& | 生成的阵型槽位列表。Generated formation slot list. |
AgentCentroid | FVector | agent 位置质心(理想位置 = FormationCenter + (Loc - Centroid))。Agent position centroid (ideal = FormationCenter + (Loc - Centroid)). |
FormationCenter | FVector | 阵型中心;未分配到槽位的 agent 落到此位置。Formation center; unassigned agents fall back here. |
ShapeForward / ShapeRight | const FVector& | 阵型局部坐标系(F/R),用于矩形环度量与阻挡判定。Formation local frame (F/R), used for rectangular ring metrics and blocker checks. |
AssignmentMode | EFormationAssignmentMode | KeepFormation 或 ReformTheLine。KeepFormation or ReformTheLine. |
RectRingAspectRatio | float | 矩形阵型环度量的纵横比(≤0 用欧氏距离 = 圆形环)。Aspect ratio for rectangular ring metrics (≤0 uses Euclidean distance = circular rings). |
OutLocations | TArray<FVector>& | 输出:每个 agent 的目标位置(与输入同序)。Output: per-agent goal position (same order as input). |
FootprintShape | EFormationFootprint | 阻挡网格的脚印族(默认 Box);网格→Box、圆形→Circle、三角→Hexagon。Blocker-grid footprint family (default Box); grid→Box, circular→Circle, triangle→Hexagon. |
Output
无返回值。副作用:填满 OutLocations(数量 = agent 数);槽位列表为空或 agent 为空时所有输出 = FormationCenter。
No return value. Side effect: fills OutLocations (count = agent count); when slots or agents are empty, all outputs equal FormationCenter.
ECS 读取包装:逐 agent 读取 FLocating.Location(缺失回退 AgentCentroid)、FDeterminism.UniqueID(缺失回退索引 i)、FMove.Z.bCanFly,然后委托给线程安全核心 AssignPositionsFromData。
ECS-reading wrapper: per agent reads FLocating.Location (fallback AgentCentroid), FDeterminism.UniqueID (fallback index i), and FMove.Z.bCanFly, then delegates to the thread-safe core AssignPositionsFromData.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MA | UMassAPISubsystem* | Mass API 子系统(可空)。Mass API subsystem (nullable). |
Agents | const TArray<FEntityHandle>& | agent 实体列表。Agent entity list. |
FormationPositions | const TArray<FVector>& | 阵型槽位列表。Formation slot list. |
AgentRadii | const TArray<float>& | 各 agent 半径(调用方预计算)。Per-agent radii (precomputed by the caller). |
AgentCentroid / FormationCenter | FVector | 质心与阵型中心。Centroid and formation center. |
ShapeForward / ShapeRight | const FVector& | 阵型局部坐标系。Formation local frame. |
AssignmentMode | EFormationAssignmentMode | 分配模式。Assignment mode. |
RectRingAspectRatio | float | 矩形环纵横比。Rectangular ring aspect ratio. |
OutLocations | TArray<FVector>& | 输出位置。Output locations. |
FootprintShape | EFormationFootprint | 阻挡网格的脚印族(默认 Box),透传给线程安全核心。Blocker-grid footprint family (default Box), forwarded to the thread-safe core. |
Output
无返回值。副作用:填充 OutLocations。
No return value. Side effect: fills OutLocations.
计算单个 agent 的阵型半径。基准为胶囊体投影到 XY 平面的包围圆半径:轴长 FCollider.Height * Scale 按上方向(FRotating.RotationQuat * FCollider.RelativeRotation)投影,端盖半径 FCollider.Radius * Scale * ColliderMult(ColliderMult 来自 FPhysicsShared,放大端盖不放大轴高,与 PBD 行为一致)。FromAvoidance 模式下再乘避障椭圆长轴系数 max(AvoidDistMult.X, AvoidDistMult.Y);最后乘以 SizeMultiplier。无 FCollider 时默认 34 * Scale。
Computes an agent's formation radius. The baseline is the capsule's bounding-circle radius projected onto the XY plane: the shaft FCollider.Height * Scale is projected along the up vector (FRotating.RotationQuat * FCollider.RelativeRotation), and the cap radius is FCollider.Radius * Scale * ColliderMult (ColliderMult from FPhysicsShared, inflating caps not the shaft, matching PBD behavior). In FromAvoidance mode the result is scaled by the avoidance ellipse's long axis max(AvoidDistMult.X, AvoidDistMult.Y); finally multiplied by SizeMultiplier. Defaults to 34 * Scale without an FCollider.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MA | UMassAPISubsystem* | Mass API 子系统。Mass API subsystem. |
Entity | const FEntityHandle& | 目标实体。Target entity. |
AgentBoundMode | EAgentBoundMode | 半径来源:FromCollider(默认)或 FromAvoidance。Radius source: FromCollider (default) or FromAvoidance. |
SizeMultiplier | float | 尺寸乘数(默认 1)。Size multiplier (default 1). |
Output
返回阵型半径(float,世界单位)。无副作用。
Returns the formation radius (float, world units). No side effects.
阵型槽位资格判定:句柄必须是存活实体(有效——未销毁/移除)、未濒死(死亡动画/待清除窗口;DyingFlag 在死亡入口就地置位,同帧可见),且能移动到槽位——缺 FMove / FMove.bEnable=false(静态道具、建筑、炮塔)或运行时 bStopActiveMovement 锁存都意味着永远走不到目标,占槽只会烂掉。战斗减员后 RTS 陈旧选集仍带着死亡句柄——幽灵不得占槽或让防线围着缺席单位重排。同步 Impl 与异步 BPTask 共用;各 Impl 在任何计数之前用它过滤输入,输出保持输入长度(1:1 契约),被剔除项散射回中心。
Formation-slot eligibility: the handle must be a live entity (valid — not destroyed/removed), not dying (death-animation / pre-despawn window; DyingFlag is set in-place at death entry, same-frame visible), AND able to move to a slot at all — missing FMove / FMove.bEnable=false (static props, buildings, turrets) or the runtime bStopActiveMovement latch mean the agent can never walk to the goal, so a slot would rot. Stale RTS selections keep dead handles after combat losses — ghosts must not reserve slots or reshape the line around missing units. Shared by the sync Impls and the async BPTask; each Impl filters its input with it before any count is taken, keeping the output at input length (1:1 contract) with dropped entries scattered to the center.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MA | const UMassAPISubsystem* | Mass API 子系统。Mass API subsystem. |
Agent | const FEntityHandle& | 待判定的 agent 实体句柄。Agent entity handle to test. |
Output
返回是否有资格占槽。无副作用(只读判定)。
Returns whether the handle is eligible for a slot. No side effects (read-only check).
位置验证与偏移:① 若配置了地面/障碍物对象类型,做向下线追踪(LineTraceMultiByObjectType,起点 = 位置 + max(Y),终点 = 位置 + min(Y));障碍物命中判无效;地面命中做坡度检查(法线 Z < cos(MaxSlope) 判为障碍);通过后位置吸附到撞击点。② 随机偏移:种子由位置内容 FNV-1a 哈希派生(相同内容不同阵型得到不同种子),每个点加随机角度 × Offset 的平面位移;偏移后重新追踪验证。无效点直接从数组中移除。注意:验证失败的点会被删除——仅对晶格槽位安全(生长补足会补),绝不可用于逐 agent 目标数组(索引映射会错位)。
Position validation and offset: ① when ground/obstacle object types are configured, runs a downward line trace (LineTraceMultiByObjectType, start = position + max(Y), end = position + min(Y)); obstacle hits invalidate the point; ground hits run the slope check (normal Z < cos(MaxSlope) treated as obstacle); on success the position snaps to the impact point. ② Random offset: the seed derives from an FNV-1a hash of the position content (different formations with the same count get different seeds); each point gets a planar displacement of random angle × Offset; points are re-traced and re-validated after offsetting. Invalid points are removed from the array. Note: points that fail validation are dropped — only safe for lattice slots (the repair loop regrows them), NEVER for per-agent goal arrays (index mapping).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 世界(可空,空则直接返回)。World (nullable; returns immediately when null). |
Positions | TArray<FVector>& | 位置数组,原地修改(吸附/偏移/移除)。Position array, modified in place (snap / offset / remove). |
Offset | float | 随机偏移半径(≤0 不偏移)。Random offset radius (≤0 disables). |
GroundObjectTypes | const TArray<TEnumAsByte<EObjectTypeQuery>>& | 地面对象类型(空 = 不追踪地面)。Ground object types (empty = no ground trace). |
ObstacleObjectTypes | const TArray<TEnumAsByte<EObjectTypeQuery>>& | 障碍物对象类型(空 = 不追踪障碍)。Obstacle object types (empty = no obstacle trace). |
GroundTraceHeightRange | const FVector2D& | 追踪高度范围(X = 起始偏移,Y = 结束偏移,内部取 max/min)。Trace height range (X = start offset, Y = end offset; max/min applied internally). |
MaxSlope | float | 最大坡度(度),0 = 不检查。Maximum slope in degrees, 0 = disabled. |
Output
无返回值。副作用:原地修改 Positions(无效点被移除)。
No return value. Side effect: Positions is modified in place (invalid points removed).
KeepFormation 平移目标解析器:逐点贴地 + 障碍/坡度校验(与 TraceAndValidate 同语义)。trace 柱内无合法地面的点(在可行走世界之外——刚体平移把它带出了平台边沿)走折返带:向锚点行进至边界后再向内一格(离边沿留余量),占用 SearchStep 大小格网上最近的空闲格——占用集预置全部原位有效目标;格心逐一地面探测,虚空格被拒,补充带沿墙/墙角自然弯折而不是堆在边沿。空间不足降级阶梯:带区搜索(折返格周围,半径随 agent 数缩放——保证能越过阵型自身已占用的侧翼)→ 锚点格周围同样搜索(有间距收拢)→ 锚点本身。有地面但被障碍/陡坡挡住的点走 ① 确定性环形搜索(MaxSearchRings 圈、SearchStep 步长、8 方向、隔圈半步偏移)——绕障碍局部变形;② 保证收敛的向心拉回——沿目标→锚点方向逐步步进探测至首个有效落点。绝不删点(每 agent 恰一个目标)。未配置地面/障碍类型则不动作。
KeepFormation translation-goal resolver: per point, ground-snap + obstacle/slope validation (same per-point semantics as TraceAndValidate). A point whose trace column has NO legal ground (outside the walkable world — the rigid translation carried it past a platform edge) relocates via the FOLD-BACK BAND: march toward the anchor to the boundary, one more cell inward (margin from the rim), then claim the nearest free cell of a SearchStep-sized occupancy grid seeded with every in-place-valid goal; cell centers are ground-probed, so void cells are rejected and the band wraps along walls and corners instead of piling on the rim. Space-insufficiency ladder: band search (size-scaled rings around the fold-back cell — the radius grows with agent count so the search can reach past the formation's own occupied flanks) → the same search around the anchor cell (center collapse WITH spacing) → the anchor itself. A point that HAS ground but is blocked by an obstacle/steep slope relocates via ① a deterministic ring search (MaxSearchRings rings of SearchStep radius, 8 directions, alternating half-step offset) — local deformation around obstacles; then ② a GUARANTEED center pull-back — marching toward the anchor in SearchStep increments until a valid spot is found. No point is ever removed (exactly one goal per agent). No ground/obstacle types configured = no-op.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 世界(线追踪)。World (line traces). |
InOutPositions | TArray<FVector>& | 平移后的目标位置,原地解析(数量不变)。Translated goal positions, resolved in place (count unchanged). |
GroundObjectTypes / ObstacleObjectTypes | const TArray<TEnumAsByte<EObjectTypeQuery>>& | 地面/障碍物对象类型(均空 = 不动作)。Ground / obstacle object types (both empty = no-op). |
GroundTraceHeightRange | const FVector2D& | 追踪高度范围。Trace height range. |
MaxSlope | float | 最大坡度(度)。Maximum slope in degrees. |
SearchStep | float | 重定位搜索步长(占用格尺寸 / 环形搜索半径步进)。Relocation search step (occupancy-cell size / ring-search radius increment). |
MaxSearchRings | int32 | 绕障碍环形搜索的最大圈数。Maximum rings for the around-obstacle ring search. |
AnchorLocation | const FVector& | 锚点(如点击点,构造保证有效)——折返与向心拉回的收敛目标。Anchor (e.g. the click point, valid by construction) — convergence target of the fold-back and center pull-back. |
Output
无返回值。副作用:原地改写 InOutPositions 中无效/出界点的位置;数组长度不变、无点删除。
No return value. Side effect: invalid/out-of-world points in InOutPositions are relocated in place; the array length is unchanged and no point is dropped.
可视化阵型结果:逐 agent(有效且有 FLocating)按配置绘制起始圆圈、起始→终点箭头、终点圆圈(均抬高 ZOffset=5)。绘制请求推入 UMassBattleSubsystem 的 LineBatchCircleQueue / LineBatchArrowQueue MPSC 队列的线程本地槽,由 ProcessDrawDebugQueues 中心排空——保持 LineBatcher 后端以在 Shipping 构建中可见(DrawDebug* 会被剥离)。
Visualizes the formation result: per agent (valid with FLocating), draws the start circle, start→end arrow, and end circle (all raised by ZOffset=5) per config. Draw requests are pushed into the thread-local slots of UMassBattleSubsystem's LineBatchCircleQueue / LineBatchArrowQueue MPSC queues, drained centrally by ProcessDrawDebugQueues — keeping the LineBatcher backend visible in Shipping builds (DrawDebug* is stripped).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
World | UWorld* | 世界(取 UMassBattleSubsystem)。World (resolves UMassBattleSubsystem). |
MA | UMassAPISubsystem* | Mass API 子系统。Mass API subsystem. |
Agents | const TArray<FEntityHandle>& | agent 实体列表。Agent entity list. |
OutLocations | const TArray<FVector>& | 分配后的目标位置。Assigned goal locations. |
OutRadii | const TArray<float>& | 各 agent 半径(缺失默认 54)。Per-agent radii (default 54 when missing). |
VisualizationConfig | const FFormationVisualizationConfig& | 可视化配置(见 MassBattleStructs.h)。Visualization config (see MassBattleStructs.h). |
Output
无返回值。副作用:向 MPSC 队列推送绘制请求。
No return value. Side effect: pushes draw requests into the MPSC queues.
网格阵型实现(由 MassBattleFuncLib::GenerateGridFormation 调用):① IsFormationSlotEligible 在任何计数之前剔除陈旧选集幽灵(输出保持输入长度 1:1,被剔除项散射回中心);② 计算各 agent 半径(≥256 个 agent 时并行)与质心;③ KeepFormation = 纯刚体平移(goal = Center + R(KeepFormationRotateDeg)·(Loc − 质心),整个排列连同队间间隙作为刚体移动,不压缩到晶格),目标经 ResolveTranslatedGoalsOnGround 贴地解析,未配置地面类型则回退点击点 Z;④ ReformTheLine 走晶格重整:ComputeBlockerExtraSlotCount(Box 脚印)+ ComputeFitAgentsSlotTarget 推目标槽位数,GenerateGridSlotPositions 生成晶格并输出实际宽高比;⑤ ValidateAndOffsetPositions 验证偏移,点数不足目标时 AppendGridGrowth 四向生长补足(≤8 轮,只验证新点、已有点绝不二次偏移);⑥ AssignPositionsToAgents 分配(矩形环纵横比 = 实际晶格宽高比,Box 脚印);⑦ Z 冻结 agent(!Z.bEnable)保持自身平面;按需可视化。
Grid formation implementation (called from MassBattleFuncLib::GenerateGridFormation): ① IsFormationSlotEligible filters stale-selection ghosts before any count is taken (output keeps input length 1:1; dropped entries scatter to the center); ② computes per-agent radii (parallelized at ≥256 agents) and the centroid; ③ KeepFormation = pure rigid translation (goal = Center + R(KeepFormationRotateDeg)·(Loc − centroid); the whole arrangement including inter-squad gaps moves as one rigid body, nothing is compressed onto a lattice), goals ground-resolved via ResolveTranslatedGoalsOnGround, falling back to the click-point Z when no ground types are configured; ④ ReformTheLine reshapes onto the lattice: ComputeBlockerExtraSlotCount (Box footprint) + ComputeFitAgentsSlotTarget derive the target slot count, and GenerateGridSlotPositions emits the lattice with the realized aspect ratio; ⑤ ValidateAndOffsetPositions validates/offsets; shortfall vs. the target is regrown by AppendGridGrowth omnidirectional growth (≤8 retries, only new points validated — existing points are never offset twice); ⑥ assigns via AssignPositionsToAgents (rectangular ring aspect = realized lattice aspect, Box footprint); ⑦ Z-frozen agents (!Z.bEnable) keep their own plane; visualizes on demand.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MA | UMassAPISubsystem* | Mass API 子系统。Mass API subsystem. |
World | UWorld* | 世界(追踪与可视化)。World (traces and visualization). |
Agents | const TArray<FEntityHandle>& | agent 实体列表。Agent entity list. |
CenterLocation | FVector | 阵型中心(世界空间)。Formation center (world space). |
ShapeData | const FAgentSpawnRectangleShapeData& | 矩形形状参数(Region / Spacing / ShapeDirection 等)。Rectangle shape parameters (Region / Spacing / ShapeDirection, etc.). |
AssignmentMode | EFormationAssignmentMode | 分配模式。Assignment mode. |
OutLocations | TArray<FVector>& | 输出位置(与 Agents 同序)。Output locations (same order as Agents). |
AgentBoundMode | EAgentBoundMode | 半径来源。Radius source. |
SizeMultiplier | float | 尺寸乘数。Size multiplier. |
VisualizationConfig | FFormationVisualizationConfig | 可视化配置。Visualization config. |
Output
无返回值。副作用:填充 OutLocations;MA 缺失或 agent 为空时输出为空数组。
No return value. Side effect: fills OutLocations; empty output when MA is missing or no agents.
圆形/多边形阵型实现(由 MassBattleFuncLib::GenerateCircularFormation 调用):① IsFormationSlotEligible 剔除幽灵(1:1 契约同网格实现);② 计算各 agent 半径(并行阈值同上);③ ComputeBlockerExtraSlotCount(Circle 脚印)+ ComputeFitAgentsSlotTarget 推目标槽位数,GenerateCircularSlotPositions 从 InnerRadius(下限 Spacing.Y/2)向外逐环生成——每环按弧长/Spacing.X 布点,多边形模式(Segments 3-32)逐角度收缩外半径,FitAgents 下环持续生长(忽略 OuterRadius,有安全上限)直到数量达标;④ 验证与偏移,不足时 AppendCircularGrowth 向外长环补足(≤8 轮,只验证新点);⑤ 质心采集;KeepFormation = 纯刚体平移(同网格实现,含 ResolveTranslatedGoalsOnGround 贴地解析);⑥ AssignPositionsToAgents 分配(环形度量 = 欧氏距离,即 RectRingAspectRatio = 0,Circle 脚印);⑦ Z 冻结处理与按需可视化。
Circular/polygon formation implementation (called from MassBattleFuncLib::GenerateCircularFormation): ① IsFormationSlotEligible filters ghosts (same 1:1 contract as the grid impl); ② computes radii (same parallel threshold); ③ ComputeBlockerExtraSlotCount (Circle footprint) + ComputeFitAgentsSlotTarget derive the target slot count, and GenerateCircularSlotPositions emits rings outward from InnerRadius (floored at Spacing.Y/2) — points per ring by arc length / Spacing.X; polygon mode (Segments 3-32) shrinks the outer radius per angle, and in FitAgents the rings keep growing (OuterRadius ignored, safety cap) until the count is met; ④ validation and offset; shortfall regrown by AppendCircularGrowth outer-ring growth (≤8 retries, only new points validated); ⑤ centroid gather; KeepFormation = pure rigid translation (same as the grid impl, including ResolveTranslatedGoalsOnGround ground resolution); ⑥ assigns via AssignPositionsToAgents (ring metric = Euclidean, i.e. RectRingAspectRatio = 0, Circle footprint); ⑦ Z-frozen handling and on-demand visualization.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MA | UMassAPISubsystem* | Mass API 子系统。Mass API subsystem. |
World | UWorld* | 世界。World. |
Agents | const TArray<FEntityHandle>& | agent 实体列表。Agent entity list. |
CenterLocation | FVector | 阵型中心。Formation center. |
ShapeData | const FAgentSpawnPolygonShapeData& | 多边形形状参数(OuterRadius / InnerRadius / Spacing / Segments 等)。Polygon shape parameters (OuterRadius / InnerRadius / Spacing / Segments, etc.). |
AssignmentMode | EFormationAssignmentMode | 分配模式。Assignment mode. |
OutLocations | TArray<FVector>& | 输出位置。Output locations. |
AgentBoundMode | EAgentBoundMode | 半径来源。Radius source. |
SizeMultiplier | float | 尺寸乘数。Size multiplier. |
VisualizationConfig | FFormationVisualizationConfig | 可视化配置。Visualization config. |
Output
无返回值。副作用:填充 OutLocations;MA 缺失或 agent 为空时输出为空数组。
No return value. Side effect: fills OutLocations; empty output when MA is missing or no agents.
三角(楔形)阵型实现(由 MassBattleFuncLib::GenerateTriangleFormation 调用;与异步 BPTask 三角分支一致——Hexagon 阻挡脚印、间距比例 Chebyshev 环):① IsFormationSlotEligible 剔除幽灵(1:1 契约);② 半径与质心;KeepFormation = 纯刚体平移(同网格实现,含 ResolveTranslatedGoalsOnGround);③ ComputeBlockerExtraSlotCount(Hexagon 脚印)+ ComputeFitAgentsSlotTarget 推目标槽位数,GenerateTriangleSlotPositions 生成楔形晶格(第 j 行 j+1 槽,顶点行朝 +ShapeDirection,包围盒居中);④ 验证与偏移,不足时 AppendTriangleGrowth 向底边长行补足(≤8 轮,只验证新点);⑤ 分配——环度量与脚印跟随阵型族:间距比例 Chebyshev 环(行 = 环,RectRingAspectRatio = Spacing.X / Spacing.Y)+ Hexagon 脚印;Spacing.Y 退化时回退圆形族默认(欧氏环 + Circle);⑥ Z 冻结处理与按需可视化。
Triangle (wedge) formation implementation (called from MassBattleFuncLib::GenerateTriangleFormation; mirrors the async BPTask triangle branch — Hexagon blocker footprint, spacing-ratio Chebyshev rings): ① IsFormationSlotEligible filters ghosts (1:1 contract); ② radii and centroid; KeepFormation = pure rigid translation (same as the grid impl, including ResolveTranslatedGoalsOnGround); ③ ComputeBlockerExtraSlotCount (Hexagon footprint) + ComputeFitAgentsSlotTarget derive the target slot count, and GenerateTriangleSlotPositions emits the wedge lattice (row j holds j+1 slots, apex row toward +ShapeDirection, bounding-box centered); ④ validation and offset; shortfall regrown by AppendTriangleGrowth base-row growth (≤8 retries, only new points validated); ⑤ assignment — ring metric and footprint follow the formation family: spacing-ratio Chebyshev rings (row = ring, RectRingAspectRatio = Spacing.X / Spacing.Y) + Hexagon footprint; degenerate Spacing.Y falls back to the circular-family defaults (Euclidean rings + Circle); ⑥ Z-frozen handling and on-demand visualization.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
MA | UMassAPISubsystem* | Mass API 子系统。Mass API subsystem. |
World | UWorld* | 世界(追踪与可视化)。World (traces and visualization). |
Agents | const TArray<FEntityHandle>& | agent 实体列表。Agent entity list. |
CenterLocation | FVector | 阵型中心。Formation center. |
ShapeData | const FAgentSpawnTriangleShapeData& | 三角形状参数(Spacing / ShapeDirection / 地面追踪配置等)。Triangle shape parameters (Spacing / ShapeDirection / ground-trace config, etc.). |
AssignmentMode | EFormationAssignmentMode | 分配模式。Assignment mode. |
OutLocations | TArray<FVector>& | 输出位置(与 Agents 同序)。Output locations (same order as Agents). |
AgentBoundMode | EAgentBoundMode | 半径来源。Radius source. |
SizeMultiplier | float | 尺寸乘数。Size multiplier. |
VisualizationConfig | FFormationVisualizationConfig | 可视化配置。Visualization config. |
Output
无返回值。副作用:填充 OutLocations;MA 缺失或 agent 为空时输出为空数组。
No return value. Side effect: fills OutLocations; empty output when MA is missing or no agents.
FitAgents 目标槽位数 = ceil(Agent 数 × SlotCountMargin) + ExtraBlockerSlots(见 ComputeBlockerExtraSlotCount);尺寸解析为(当前禁用的)Fixed 分支时返回 0。
FitAgents slot-count target = ceil(NumAgents × SlotCountMargin) + ExtraBlockerSlots (see ComputeBlockerExtraSlotCount); returns 0 when sizing resolves to the (currently disabled) Fixed branches.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
NumAgents | int32 | agent 数(通常为过滤后的有效数)。Agent count (usually the filtered valid count). |
SizingMode | EFormationSizingMode | 尺寸模式(Fixed / FitAgents;Fixed 分支返回 0)。Sizing mode (Fixed / FitAgents; Fixed branches return 0). |
SlotCountMargin | float | 槽位余量比例。Slot-count margin ratio. |
ExtraBlockerSlots | int32 | 大单位额外槽位(默认 0)。Large-agent extra slots (default 0). |
Output
返回目标槽位数(Fixed 分支为 0)。无副作用(纯数学)。
Returns the target slot count (0 for Fixed branches). No side effects (pure math).
大单位的额外槽位需求:半径超过半个最小槽距的 agent 是 blocker,其排除脚印覆盖多个格位(脚印族跟随阵型——网格 Box、圆形 Circle、三角 Hexagon)。故意按脚印不重叠高估——多余槽位在 ReformTheLine 中被压拢、在 KeepFormation 中闲置,而短缺会让被挤走的 agent 堆到阵型中心。纯数学,只依赖半径多重集。
Extra FitAgents slot demand from large agents: each agent whose radius exceeds half the minimum slot spacing becomes a blocker whose exclusion footprint covers multiple lattice cells (footprint family follows the formation — Box for grid, Circle for circular, Hexagon for triangle). Deliberately a disjoint-footprint OVERestimate: extra slots compact away in ReformTheLine and stay unused in KeepFormation, while a shortfall piles displaced agents at the formation center. Pure math on the radii multiset.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
AgentRadii | const TArray<float>& | 各 agent 半径。Per-agent radii. |
SlotSpacingX / SlotSpacingY | float | 槽位间距(取二者较小的一半作 blocker 阈值)。Slot spacings (half the minimum is the blocker threshold). |
Footprint | EFormationFootprint | 排除脚印族。Exclusion footprint family. |
Output
返回额外槽位需求数。无副作用(纯数学)。
Returns the extra slot demand. No side effects (pure math).
网格晶格生成(纯数学、线程安全):Fixed 模式 NumX/NumY = Floor(Region/Spacing),逐点复现旧版 authored 画布布局;FitAgents 模式按 authored 长宽比解出点数比 W/H(使 (W-1)·SX / ((H-1)·SY) ≈ Region.X/Region.Y),取最小 W×H ≥ 目标槽位数——authored 尺寸仅作长宽比,槽位始终够用。OutRealizedAspectRatio = NumX·SX / (NumY·SY)(退化时 1.f),喂给矩形环形压缩。
Grid lattice generation (pure math, thread-safe): Fixed mode NumX/NumY = Floor(Region/Spacing), reproducing the legacy authored-canvas layout exactly; FitAgents mode solves the point-count ratio W/H from the authored aspect so (W-1)·SX / ((H-1)·SY) ≈ Region.X/Region.Y with minimal W×H ≥ TargetSlotCount — the authored size only sets the aspect ratio, so slots always suffice. OutRealizedAspectRatio = NumX·SX / (NumY·SY) (1.f if degenerate), feeding rectangular ring compaction.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
ShapeData | const FAgentSpawnRectangleShapeData& | 矩形形状参数。Rectangle shape parameters. |
TargetSlotCount | int32 | 目标槽位数(FitAgents;Fixed 分支忽略)。Target slot count (FitAgents; ignored by Fixed branches). |
CenterLocation | const FVector& | 阵型中心。Formation center. |
ShapeForward / ShapeRight | const FVector& | 阵型局部坐标系。Formation local frame. |
Output
无返回值。输出:追加晶格点到 OutPositions;OutNumX / OutNumY 行列数(生长锚点);OutRealizedAspectRatio 实际物理宽高比。
No return value. Outputs: lattice points appended to OutPositions; OutNumX / OutNumY dims (growth anchors); OutRealizedAspectRatio realized physical aspect.
不发射晶格直接算实际物理宽高比 (NumX·SX)/(NumY·SY)——供只携带形状数据的路径(如异步任务的派发步骤)做环形压缩。AgentRadii 参与和生成器一致的 blocker 额外槽位目标,保证宽高比与发射晶格一致。退化时返回 1.f。
Realized physical aspect (NumX·SX)/(NumY·SY) without emitting the lattice — for ring compaction on paths that only carry the shape data (e.g. the async task's dispatch step). AgentRadii feed the same blocker-extra slot target the generators use, so the aspect matches the emitted lattice. Returns 1.f when degenerate.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
ShapeData | const FAgentSpawnRectangleShapeData& | 矩形形状参数。Rectangle shape parameters. |
AgentRadii | const TArray<float>& | 各 agent 半径(参与目标槽位数推导)。Per-agent radii (feed the slot-target derivation). |
Output
返回实际宽高比(退化时 1.f)。无副作用。
Returns the realized aspect ratio (1.f when degenerate). No side effects.
三角(楔形)晶格生成:第 j 行 j+1 槽,行内间距 Spacing.X,行间距 Spacing.Y,顶点行(1 槽)朝 +ShapeDirection,包围盒居中。Fixed 模式行数受 Min(Floor(Region.X/SX), Floor(Region.Y/SY)) + 1 限制;FitAgents 模式取最小 Rows 使 Rows·(Rows+1)/2 ≥ 目标槽位数。
Triangle (wedge) lattice generation: row j holds j+1 slots, in-row pitch Spacing.X, row pitch Spacing.Y, apex row (1 slot) toward +ShapeDirection, bounding-box centered. Fixed mode caps rows at Min(Floor(Region.X/SX), Floor(Region.Y/SY)) + 1; FitAgents mode takes the smallest Rows with Rows·(Rows+1)/2 ≥ TargetSlotCount.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
ShapeData | const FAgentSpawnTriangleShapeData& | 三角形状参数。Triangle shape parameters. |
TargetSlotCount | int32 | 目标槽位数。Target slot count. |
CenterLocation / ShapeForward / ShapeRight | const FVector& | 阵型中心与局部坐标系。Formation center and local frame. |
Output
无返回值。输出:追加晶格点到 OutPositions;OutNumRows 行数(生长锚点)。
No return value. Outputs: lattice points appended to OutPositions; OutNumRows row count (growth anchor).
圆形/多边形环晶格生成:Fixed 模式环数受 OuterRadius 界定(含逐角度多边形裁剪);FitAgents 模式环持续生长(忽略 OuterRadius,有安全上限)直到数量 ≥ 目标槽位数。OutNextRingIdx = 首个未发射环——AppendCircularGrowth 的续接点。
Circular/polygon ring lattice generation: Fixed mode bounds rings by OuterRadius (including the per-angle polygon clip); FitAgents mode keeps growing rings (OuterRadius ignored, safety cap) until count ≥ TargetSlotCount. OutNextRingIdx = first unemitted ring — the resume point for AppendCircularGrowth.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
ShapeData | const FAgentSpawnPolygonShapeData& | 多边形形状参数。Polygon shape parameters. |
TargetSlotCount | int32 | 目标槽位数。Target slot count. |
CenterLocation / ShapeForward / ShapeRight | const FVector& | 阵型中心与局部坐标系。Formation center and local frame. |
Output
无返回值。输出:追加晶格点到 OutPositions;OutNextRingIdx 续接环下标。
No return value. Outputs: lattice points appended to OutPositions; OutNextRingIdx resume ring index.
FitAgents 的 trace 删点补足:追加晶格点且不移动已有点,发射直到 MinNewSlots 个新点就绪(或形状耗尽)。调用方单独验证新点并追加幸存者,因此任何点不会被偏移两次;返回 0 = 无可生长。网格生长是四向的:晶格边界(MinX..MaxX、MinY..MaxY)在四条边上轮转扩展,锚定在初始生成的行列数(OriginNumX/OriginNumY)上——中心贴墙角的阵型也能找到开阔侧,扎进墙里的发射点在调用方的 trace 中被丢弃,自由方向持续积累。三角生长向底边长行;圆形生长向外长环(经 InOutNextRingIdx 续接)。
FitAgents trace-shortfall repair: appends lattice points WITHOUT moving existing ones, emitting until MinNewSlots new points are available (or the shape is exhausted). Call sites validate the new points separately and append the survivors, so no point is ever offset twice; 0 = nothing left to grow. Grid growth is OMNIDIRECTIONAL: the lattice bounds (MinX..MaxX, MinY..MaxY) extend round-robin on all four edges, anchored at the ORIGINAL generation dims (OriginNumX/OriginNumY) — a formation pinned against a wall corner still finds the open side; emissions into the wall die at the call site's trace while the free directions accumulate. Triangle growth extends base rows; circular growth adds outer rings (resumed via InOutNextRingIdx).
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
ShapeData | const FAgentSpawn*ShapeData& | 对应形状参数(矩形/三角/多边形)。Matching shape parameters (rectangle / triangle / polygon). |
OriginNumX / OriginNumY / OriginNumRows | int32 | 初始生成的行列数(生长锚点;仅网格/三角)。Original generation dims (growth anchors; grid/triangle only). |
InOutMinX / InOutMaxX / InOutMinY / InOutMaxY | int32& | 晶格边界,跨轮持续扩展(仅网格)。Lattice bounds, extended across rounds (grid only). |
InOutNextRowIdx / InOutNextRingIdx | int32& | 续接下标(行/环;仅三角/圆形)。Resume index (row / ring; triangle / circular only). |
MinNewSlots | int32 | 本轮至少要发射的新点数(通常 = 目标 − 现存)。Minimum new points to emit this round (usually target − current). |
CenterLocation / ShapeForward / ShapeRight | const FVector& | 阵型中心与局部坐标系。Formation center and local frame. |
Output
返回发射的新点数(0 = 无可生长)。副作用:新点追加进 OutNewPoints,边界/续接下标前移。
Returns the emitted point count (0 = nothing left to grow). Side effects: new points appended to OutNewPoints; bounds / resume indices advanced.
管线角色 Pipeline Role
调用链:MassBattleFuncLib::GenerateGridFormation / GenerateCircularFormation / GenerateTriangleFormation(蓝图节点)→ GenerateGridFormationImpl / GenerateCircularFormationImpl / GenerateTriangleFormationImpl → AssignPositionsToAgents(ECS 读取)→ AssignPositionsFromData(线程安全核心,按飞行状态分区)。槽位晶格族(ComputeFitAgentsSlotTarget / ComputeBlockerExtraSlotCount / Generate*SlotPositions / Append*Growth)与资格过滤 IsFormationSlotEligible 另被异步任务 UMassBattleBPTaskGenerateFormation 复用(派发步骤),ComputeGridRingAspectRatio 供其派发步骤做环形压缩——同步与异步路径共享同一晶格数据源。可视化经 UMassBattleSubsystem::ProcessDrawDebugQueues 中心排空(LineBatch* MPSC 队列)。分配核心无外部调用——其内部拍卖/气泡/修复算法全部为文件局部静态函数。确定性纪律:所有排序与随机种子都由 UniqueID 或位置内容派生,双端一致。
Call chain: MassBattleFuncLib::GenerateGridFormation / GenerateCircularFormation / GenerateTriangleFormation (Blueprints) → GenerateGridFormationImpl / GenerateCircularFormationImpl / GenerateTriangleFormationImpl → AssignPositionsToAgents (ECS reads) → AssignPositionsFromData (thread-safe core, partitioned by flying status). The slot-lattice family (ComputeFitAgentsSlotTarget / ComputeBlockerExtraSlotCount / Generate*SlotPositions / Append*Growth) and the eligibility filter IsFormationSlotEligible are also reused by the async task UMassBattleBPTaskGenerateFormation (dispatch step), with ComputeGridRingAspectRatio feeding its dispatch-step ring compaction — sync and async paths share the single lattice source of truth. Visualization is drained centrally by UMassBattleSubsystem::ProcessDrawDebugQueues (LineBatch* MPSC queues). The assignment core has no external callers — its auction/bubble/repair algorithms are all file-local static functions. Determinism discipline: all sort keys and random seeds derive from UniqueID or position content, identical across peers.