① CharacterTransformBase(遁光·飞行)
继承 ACharacter,非组件类;3161 行 .cpp;右键遁光 + 空格飞行 + MPC 溶解过渡。
TransformBase 是角色的形态变换基类,**不是**一个挂在角色上的 Component。核心结构:
// TransformCharacter.h(脱敏后)
UCLASS()
class TEST_API CharacterTransformBase : public ACharacter
{
GENERATED_BODY()
public:
// 形态系统
TArray> Forms; // 可用形态列表
int32 FormIndex = 0; // 当前形态索引
FOnFormChanged OnFormChanged; // 形态变化委托(蓝图绑定)
// 遁光/飞行
UFUNCTION(BlueprintCallable) TransformToNextForm();
UFUNCTION(BlueprintCallable) TransformToForm(int32 Index);
UFUNCTION(BlueprintPure) GetCurrentFormClass();
// 🆕 2026-09-29 新增:AI 专用遁光接口(CharacterTransformBase.h:419-432)
UFUNCTION(BlueprintCallable) ExecuteEnterTransformForAI();
UFUNCTION(BlueprintCallable) ExecuteExitTransformForAI();
};
遁光时序(右键触发 / AI ForAI 接口复刻):
StartDissolveOut → Tick 每帧 Dissolve = 1-progress(0.2s 跑完) → 遁光状态切换:bIsInTransformedForm = true → MOVE_Flying,MaxWalkSpeed=4500,角色隐藏 → 退出反向:StartDissolveIn → Dissolve 拉回 1 → MOVE_Walking,MaxWalkSpeed=默认,角色恢复
关键点:遁光状态由 bIsInTransformedForm 布尔原子切换,C++ 守卫保证不会在过渡窗口内重复 Enter/Exit(日志 SKIPPED 实锤)。
② CharacterBase(战斗基类,继承 TransformBase)
7516 行 .cpp;五连普攻、三连追踪弹、闪电链、蓄力普攻、E键护盾。
战斗 C++ 不是"一个大函数",而是几个独立的技能入口函数,每个函数只负责本技能的执行时序和状态管理,效果(特效/蒙太奇/伤害投递)由蓝图图表调用 C++ 接口触发:
| 函数 | 职责 |
SpawnCombo3BulletVolley() | 三连追踪弹生成入口(三连普攻的 C++ 锚点) |
CollectEnemyPawns(From, Out) | 范围搜敌(AI 遁光追击的 TargetActor 来源) |
TriggerCombo4Lightning() | 闪电链触发(调蓝图 ChainLightning 事件) |
StartCombo5BulletRing() / SpawnOneCombo5Bullet() | 五连环形弹幕每段生成 |
DevDash / DevAttack / DevAura / DevSwordQi | 开发期快捷调试入口(PIE 里按 F 键临时触发技能) |
OnMontageEnded | 蒙太奇完成回调 → ResetAttackState → 攻击状态机清零(蓝图再复杂也不丢状态) |
E键护盾:CharacterBase.cpp:7268 Tick 轮询物理 E 键——按下时生成一个临时 CollisionSphere Block on WorldDynamic。
③ TimeOfDayManager(昼夜循环)
969 行 .cpp;单例统一驱动 DirectionalLight / SkyAtmosphere / PostProcess / 角色材质 MPC。
昼夜系统不是在蓝图里摆一张 Timeline——TimeOfDayManager 是一个 Actor,关卡里放一个,三个子系统全挂它:
// TimeOfDayManager.cpp 关键函数 float GetDaylightFactor(Hours) // 0.0(夜)→1.0(正午) 线性插值 void ApplySunMoonIntensity(Actor, Hours) // 驱动 DirectionalLight + SkyAtmosphere void SetTimeOfDay(TargetHour) // 手动跳时(调试/UI 面板) void ResumeDayCycle() // 恢复 1h/现实 2min 的真实时间流速 float GetCurrentTimeOfDay() // 对外暴露当前小时数
三处共用:① DirectionalLight 角度(Transform Rotation.X 映射小时数)② SkyAtmosphere(太阳强度 / 大气厚度)③ PostProcess AutoExposureBias(夜景压暗 + 角色材质 EffectBrightness 缩放 + 技能特效 MPC EmissiveScale 昼夜曲线)。同一个 Hours 值驱动三处,不会出现"天黑了但角色还亮得像白天"。
④ ASwordQOrbitManager(六剑环绕)
581 行 .cpp;Tick 每帧更新六把飞剑的圆周/螺旋轨道。
// SwordQOrbitManager.cpp 关键流程
Tick(DeltaTime)
├─ HandleQPressed() // Q 键按下 → StartWindup()
│ └─ 蓄力 0.8s 后 SpawnSwords() (生成 6 把飞剑 Actor)
└─ 每帧更新圆周位置
└─ SetActorLocation(Swords[i], Center + Offset[i])
Offset 由 sin/cos(θ+i*60°) 计算,θ 每帧 += 转速
⑤ 实测踩坑(全部实测定案,不是推演)
遁光静默退出三修(V171,2026-09-20)。"遁光中按空格 → 退出遁光接空格飞行"这条路径原本是静默退出(跳过闪光与溶解),但它跳得太多:
- 退出精灵缺失:静默退出整段不调
SpawnTransformSpriteVFX()(当初按"不要变成星星"删掉的)。修:补调一次,必须放在 ExecuteExitTransform 之前——该函数末尾(cpp:1521)把 bIsInTransformedForm 置 false;放在后面会误播 Enter 特效(日志 SKIPPED 实锤)。 - 飞行中角色隐形:StartDissolveOut 跑完 Dissolve=0(角色全溶解);静默路径跳过 StartDissolveIn → Dissolve 永远停在 0。修:静默退出里把终值直接写 Dissolve=1 / Opacity=1,无插值 = 无溶解演出。
- 之后进/出遁光炸出飞行停止特效:V163 注入的合成空格
IE_Pressed只有按下沿,没有配对释放;且注入时机比玩家松手晚 → 输入侧空格永远算"按着",松开沿永不到达。修:①置bSpaceFlightLatched=true(下一帧即走"无缝衔接空格飞"分支);②两条飞行停止包在 SetSprintEvent(false) 之后各补一个配对的IE_Released清账。
CharacterMovement 默认 MOVE_Flying(AI 悬空隐形)。TransformBase.cpp:1378-1380、CharacterBase.cpp:1068-1076 默认悬浮形态 MOVE_Flying。AI 出生即 Flying 永不落地,Launch 后无重力刹不住 → 悬空 44m "隐形"。修:AI 子蓝图 BeginPlay 强制 SetMovementMode(Walking)(PIE 105s 验证 C++ 不会打回)。