FlowFieldModifier.h
Source/FlowFieldCanvas/Public/FlowFieldModifier.h
概述 Overview
流场修改器的基类文件。定义混合模式枚举 EFFBlendMode(Replace / Blend / Erase)与所有 modifier 的公共基类 AFlowFieldModifier(AActor)。三种具体修改器家族——成本(AFlowFieldCostModifier)、方向(AFlowFieldDirModifier)、网格(AFlowFieldGridModifier)——都继承自本类;公共开关 bEnable、混合模式 BlendMode 与回指所属流场的 FlowField 指针在此定义,由 AFlowField::GetAllModifiers 收集或 AFlowField::RegisterModifier 注册时写入。本类还承载推模式注册:BeginPlay 时每个 modifier 报到静态 LiveModifiers 表并向同世界全部场自注册——运行时独立 spawn 的 modifier 无需 full rebuild 即可被流场感知(与 AFlowField::LiveInstances 互为对偶,双向发现免疫加载顺序)。
The base-class file of flow field modifiers. Defines the blend-mode enum EFFBlendMode (Replace / Blend / Erase) and the common base class AFlowFieldModifier (an AActor). All three modifier families — cost (AFlowFieldCostModifier), direction (AFlowFieldDirModifier) and grid (AFlowFieldGridModifier) — derive from it; the shared enable toggle bEnable, the blend mode BlendMode, and the back-reference FlowField pointer are defined here, stamped by AFlowField::GetAllModifiers during collection or by AFlowField::RegisterModifier on registration. The class also carries the push-model registration: on BeginPlay every modifier checks into the static LiveModifiers table and self-registers with every same-world field — a runtime-spawned modifier becomes visible to flow fields without a full rebuild (the dual of AFlowField::LiveInstances; two-way discovery is load-order-proof).
EFFBlendMode UENUM
修改器与流场数据的混合方式,所有 modifier 子类共用一个语义。
How a modifier blends with the flow field data; one shared semantic for all modifier subclasses.
| 值 Value | 说明 Description |
|---|---|
Replace | 直接覆盖目标值(如格子 cost / 方向)。Directly overwrite the target value (cell cost / direction). |
Blend | 与当前值各取 50% 平均((current + new) / 2)。Average with the current value 50/50 ((current + new) / 2). |
Erase | 恢复为原始值(成本/类型回退到 InitialCellsArray;方向回退到 BaseDirArray / BaseNavMeshDirMap),消除之前修改器的影响。Restore the original value (cost/type from InitialCellsArray; direction from BaseDirArray / BaseNavMeshDirMap), removing the effects of previous modifiers. |
AFlowFieldModifier UCLASS
所有流场修改器 Actor 的基类。构造函数创建默认场景根组件与编辑器 Billboard 图标;带 Billboard 组件、bEnable 开关、BlendMode 混合模式,以及由流场回填的 FlowField 软引用。生命周期两端做推模式注册/注销:BeginPlay 报到 LiveModifiers 并注册到同世界全部场,EndPlay 对称撤销。具体修改行为全部由子类实现。
Base class of all flow field modifier actors. The constructor creates a default scene root and an editor Billboard icon; carries the Billboard component, the bEnable toggle, the BlendMode blend mode, and the FlowField soft reference back-filled by the flow field. Both lifecycle ends do push-model registration: BeginPlay checks into LiveModifiers and registers with every same-world field; EndPlay symmetrically withdraws. All actual modification behavior lives in subclasses.
继承 Inheritance
公开方法 Public Methods
启用每帧 Tick(PrimaryActorTick.bCanEverTick = true),创建默认场景根 DefaultSceneRoot,并创建附加其上的 Billboard 编辑器图标组件。
Enables per-frame tick (PrimaryActorTick.bCanEverTick = true), creates the default scene root DefaultSceneRoot, and creates a Billboard editor icon component attached to it.
Input
无参数。
No parameters.
Output
无返回值。副作用:创建根组件与 Billboard 组件。
No return value. Side effect: creates the root and Billboard components.
编辑器构造回调:先调用父类,再调用 DrawDebug()——若 FlowField 软引用已有效,则触发所属流场重绘调试可视化。
Editor construction callback: calls the parent, then DrawDebug() — which triggers a debug redraw of the owning flow field if the FlowField soft reference is valid.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Transform | const FTransform& | 构造时使用的变换,透传给父类。Transform used for construction; forwarded to the parent. |
Output
无返回值。副作用:当 FlowField 有效时调用其 DrawDebug()。
No return value. Side effect: calls DrawDebug() on the flow field when FlowField is valid.
游戏启动回调:① 调用父类;② AddUnique 报到静态 LiveModifiers 注册表;③ 推模式自注册——遍历 AFlowField::LiveInstances,对同世界(GetWorld() 相同,PIE 双世界互不串扰)的每个存活流场调用 RegisterModifier(this)。运行时独立 spawn 的 modifier 由此无需 full rebuild 即被感知;对 Include/Attach 成员幂等(GetAllModifiers 去重合并);全部家族皆空间圈选型,圈外的场对其自然 no-op。更晚 BeginPlay 的场经自身 LiveModifiers 扫描收编本 modifier——任意加载顺序收敛。
Game-start callback: ① calls the parent; ② checks into the static LiveModifiers registry via AddUnique; ③ push-model self-registration — iterates AFlowField::LiveInstances calling RegisterModifier(this) on every live same-world flow field (same GetWorld(), keeping PIE dual-worlds apart). A runtime-spawned standalone modifier is thereby seen without a full rebuild; idempotent against Include/Attach membership (GetAllModifiers merges dedup'd); all flavors are spatial (volume/spline-scoped), so fields outside the shape simply no-op on it. Fields that BeginPlay later adopt this modifier via their own LiveModifiers scan — any load order converges.
Input
无参数。
No parameters.
Output
无返回值。副作用:加入 LiveModifiers;向同世界全部场注册(进入各场的运行时注册集合与活动列表)。
No return value. Side effects: joins LiveModifiers; registers with every same-world field (entering each field's runtime-registration set and active lists).
游戏结束回调,BeginPlay 的镜像:遍历 AFlowField::LiveInstances,对同世界的每个存活流场调用 UnregisterModifier(this)(从运行时集合与活动列表移除),随后从 LiveModifiers 移除自身,最后调用父类。活动列表是弱引用——跳过这步不会悬挂,但残留条目会累积、Apply 趟持续为其付出 IsValid 检查。
Game-end callback, the mirror of BeginPlay: iterates AFlowField::LiveInstances calling UnregisterModifier(this) on every live same-world flow field (removing it from the runtime set and the active list), then removes itself from LiveModifiers, then calls the parent. The active lists are weak — skipping this would not dangle, but stale entries would accumulate and Apply passes would keep paying IsValid checks on them.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
Reason | const EEndPlayReason::Type | 结束原因,透传给父类。End-play reason; forwarded to the parent. |
Output
无返回值。副作用:从全部同世界场与 LiveModifiers 注销。
No return value. Side effects: unregisters from every same-world field and from LiveModifiers.
每帧回调,仅调用父类实现,无额外逻辑。
Per-frame callback; only calls the parent implementation, no extra logic.
Input
| 参数 Param | 类型 Type | 说明 Description |
|---|---|---|
DeltaTime | float | 本帧时间步长(秒),当前未使用。Frame delta time in seconds; currently unused. |
Output
无返回值,无副作用。
No return value, no side effects.
若 FlowField 软引用有效,调用其 DrawDebug() 让流场按当前配置重算并重绘。注释掉的 UFUNCTION 声明表明它原本是编辑器可调用按钮,当前无 UFUNCTION 标记。
If the FlowField soft reference is valid, calls its DrawDebug() so the field recalculates and redraws with current settings. The commented-out UFUNCTION declaration shows it was originally an editor-invokable button; it currently carries no UFUNCTION marker.
Input
无参数。
No parameters.
Output
无返回值。副作用:所属流场重算并重绘调试可视化(若 FlowField 有效)。
No return value. Side effect: the owning flow field recalculates and redraws its debug visualization (when FlowField is valid).
成员变量 Members
| 名称 Name | 类型 Type | 默认值 | 说明 Description |
|---|---|---|---|
Billboard | TObjectPtr<UBillboardComponent> | — | 编辑器中的 Billboard 图标组件(VisibleDefaultsOnly)。Billboard icon component in the editor (VisibleDefaultsOnly). |
bEnable | bool | true | 总开关:流场收集时(GetAllModifiers 之后的 Apply 循环)跳过关闭的 modifier。Master toggle: the flow field's apply loops skip disabled modifiers after GetAllModifiers. |
BlendMode | EFFBlendMode | Replace | 混合模式(见 EFFBlendMode)。Blend mode (see EFFBlendMode). |
FlowField | TSoftObjectPtr<AFlowField> | — | 所属流场软引用,由 AFlowField::GetAllModifiers 收集或 AFlowField::RegisterModifier 注册时写入(支持挂到流场 Actor 下、用 IncludeModifiers 显式引用,或运行时推模式注册)。Soft reference to the owning flow field, stamped by AFlowField::GetAllModifiers during collection or by AFlowField::RegisterModifier on registration (modifiers may be attached to the flow field actor, referenced via IncludeModifiers, or registered at runtime through the push model). |
LiveModifiers | static TArray<TWeakObjectPtr<AFlowFieldModifier>> | 空 | 推模式注册表(AFlowField::LiveInstances 的对偶):每个在线 modifier 于 BeginPlay 报到;场的 BeginPlay 收编同世界成员(免疫加载顺序——哪侧后启动哪侧完成绑定)。两侧扫描点均按世界过滤,PIE 双世界互不串扰。静态、非复制:注册是端本地事务——锁步下跨线的是(服务器构建的)基底流,绝不是注册本身。Push-model registry (the counterpart of AFlowField::LiveInstances): every live modifier checks in here on BeginPlay; a field's BeginPlay adopts same-world members (load-order-proof — whichever side starts later completes the binding). Both scan sites filter per world, keeping PIE dual-worlds apart. Static, non-replicated: registration is a LOCAL affair — under lockstep the substrate stream (server-built) is what crosses the wire, never registrations. |
补充说明 Notes
头文件中注释掉了 bEditorLiveUpdate(DisplayPriority = 2 的编辑器实时更新开关),当前未启用。
The bEditorLiveUpdate property (DisplayPriority = 2, editor live update toggle) is commented out in the header and currently disabled.