This article records the complete development process of a feature study project for validating the character transformation, flight, and boost dash. The project is based on the UE 5.8.1 engine, with C++ implementing the core logic and Blueprints used only to configure asset references.
— Development record preface
1. Project goals
Implement a complete character form transformation and flight-and-dash system, including the following features:
- Press
Tto enter/exit the transformed form - After transforming, the character flies forward automatically, and
W/A/S/Dsteers up/down/left/right - After transforming, the field of view (FOV) widens from 80 to 120
- After transforming, press the right mouse button to enter boost mode: speed rises sharply, and a one-shot boost VFX plays
- Press the right mouse button again to exit boost mode
- A flash transition VFX plays at the moment of transformation, and the form switches after 0.4 s
- When exiting the transformation, the character stops moving immediately and does not keep surging forward
- The form switch is accompanied by a dissolve transition effect (MPC material parameter set reserved)
2. Project structure and tech stack
- Engine version: Unreal Engine 5.8.1
- Development method: C++ core logic + Blueprint configuration references
- Core C++ class:
TransformBase(inheritsACharacter)
Key assets
| Asset | Purpose |
|---|---|
BP_ThirdPersonCharacter | Official third-person character Blueprint; parent class changed to TransformBase |
BP_Projectile_Ice | Transformation effect Blueprint Actor containing multiple Niagara components |
NS_StarSkill002 | Persistent purple sphere particle after transformation |
NS_Dash | Transformation burst trail VFX (changed to the Ribbon renderer) |
NS_FlyLine_001 | Custom trail VFX |
NS_JiaSu | Boost VFX |
NS_SpriteSpawn | Transformation flash transition VFX |
MPC_Dissolve | Dissolve effect material parameter set |
3. Production method and core implementation
3.1 Input binding
The project uses the legacy UInputComponent rather than Enhanced Input, so keys are bound directly with BindKey:
EKeys::T: triggers entering/exiting the transformed formEKeys::RightMouseButton: toggles boost mode
Binding location: TransformBase::SetupPlayerInputComponent
3.2 Form-switching flow
After pressing T, the flow first enters the 0.4 s flash transition stage.
Entering the transformation
- Call
StartDissolveOut()to begin the dissolve fade-out - Spawn the
NS_SpriteSpawnflash VFX at the character position - Execute
ExecuteEnterTransform()after 0.4 s - Hide the character mesh, spawn the transformation effect Actor, switch to
MOVE_Flyingmode - Set FOV to 120
Exiting the transformation
- Immediately set
bIsInTransformedForm = falseand stop the flight logic - Immediately zero the velocity, stop movement, and switch back to
MOVE_Walking - Destroy the transformation effect Actor and restore the character mesh
- Call
StartDissolveIn()to begin the dissolve fade-in - Execute
ExecuteExitTransform()after 0.4 s - Restore FOV to 80
3.3 Flight control
Flight is implemented in Tick() after transformation:
- Automatic forward flight:
ViewForward * AutoFlySpeed W: fly up (world Z+)S: fly down (world Z-, with ground detection to avoid clipping through the ground)A: fly left (left of the view direction)D: fly right (right of the view direction)
| State | Auto flight speed | Steering speed |
|---|---|---|
| Normal | 1200 cm/s | 800 cm/s |
| Boost | 5000 cm/s | 4000 cm/s |
The early implementation used AddMovementInput, but because it is limited by CharacterMovementComponent::MaxAcceleration, the sense of acceleration was not obvious. The final version computes DesiredVelocity directly and smooths MoveComp->Velocity via FMath::VInterpTo, significantly improving acceleration response.
3.4 Boost system
The right mouse button toggles the bIsBoosting state:
- Entering boost: spawn the
NS_JiaSuboost VFX at the character position and switch the speed to boost parameters - Exiting boost: only restore the speed; do not replay the VFX
3.5 Niagara VFX and velocity handoff
The effect Actor spawned after transformation contains multiple Niagara components. In Tick(), the character's world velocity GetVelocity() is read and handed to Niagara via SetVariableVec3("User.FlyVelocity", FlyVel), driving trail, inertia swing, and other particle effects.
4. Issues and fixes during development
| Issue | Root cause | Fix |
|---|---|---|
Pressing T does nothing | PlayerInputComponent is NULL in SetupPlayerInputComponent | Bind the T key directly inside that function via BindKey |
| No Niagara VFX visible after transformation | Wrong path; the Blueprint CDO serializes FormNiagaraSystem as None | Correct the path to /Game/Test_02/VFX/BlackVFX/NS_StarSkill002; repair the CDO reference with a Python script |
| Particles do not disappear after exiting transformation | On exit, only the mesh is hidden; the effect Actor is not destroyed | Call SpawnedTransformVFX->Destroy() and clear the pointer |
| Post-transformation FOV change has no effect | APlayerController::SetFOV() is overridden by the camera component | Use PlayerCameraManager->SetFOV() instead |
| Character keeps surging forward after exiting transformation | CharacterMovementComponent retains inertial velocity | Immediately set non-transformed, zero Velocity, call StopMovementImmediately() |
| Boost VFX works but the speed does not change | The Blueprint CDO serializes the speed as 0; AddMovementInput is limited by MaxAcceleration | Force-reset the speed in BeginPlay(); set Velocity directly |
| Character material lost and turned gray | Adding dissolve nodes to M_Mannequin left OneMinus unconnected correctly | Delete the wrong node and reconnect with the correct pin name "None" |
| Ribbon trail not visible | Niagara uses local space, so its own velocity is 0 | Switch to world-space simulation, add the Inherit Velocity and Drag modules |
| Blueprint compile-error popup | Deprecated template assets BP_Dummy_Character, W_Projectiles_HUD | Unrelated to the transformation system; click "Run in editor" and continue testing |
5. Modified code files
5.1 Source/Test/Public/TransformCharacter.h
- Added
BoostEffect: boost Niagara VFX - Added
bIsBoosting: boost state flag - Added
NormalFlySpeed,NormalSteerSpeed,BoostFlySpeed,BoostSteerSpeed: flight speed parameters - Added
OnBoostInput(): right-mouse-boost input handler - Added
TransformFlashEffect,TransformFlashDelay: flash transition VFX and delay - Added
DissolveMPC,DissolveParamName: dissolve-effect MPC asset and parameter name - Added
TransformVFXBlueprint,SpawnedTransformVFX: transformation effect Blueprint Actor class and instance - Added dissolve-related private members and functions
5.2 Source/Test/Private/TransformCharacter.cpp
- Load default assets in the constructor:
BP_Projectile_Ice,NS_SpriteSpawn,NS_JiaSu - Set flight-speed defaults in
BeginPlay()to prevent Blueprint CDO override - Bind
Tand the right mouse button inSetupPlayerInputComponent() - Implement dissolve animation, flight control, and Niagara velocity handoff in
Tick() OnTransformInput()implements the full enter/exit transformation flowOnBoostInput()implements boost-mode toggling and one-shot VFX playbackExecuteEnterTransform()/ExecuteExitTransform()implement the formal enter/exit transformationStartDissolveOut()/StartDissolveIn()control the dissolve direction
6. Key parameter summary
| Parameter | Value | Description |
|---|---|---|
| Normal auto flight speed | 1200 cm/s | Auto-forward speed after transformation when the right mouse is not held |
| Normal steering speed | 800 cm/s | WASD steering speed after transformation |
| Boost auto flight speed | 5000 cm/s | Auto-forward speed after right-mouse boost |
| Boost steering speed | 4000 cm/s | WASD steering speed after right-mouse boost |
| Transformation FOV | 120 | Field of view after transformation |
| Default FOV | 80 | Field of view restored after exiting transformation |
| Flash delay | 0.4 s | Time from pressing T to the formal transformation |
| Transformation cooldown | 0.5 s | Cooldown to prevent rapid repeated triggering |
| Velocity interpolation rate | 8.0 | Transition rate of VInterpTo |
7. Takeaways
- Blueprint CDO overwrites C++ default values: for critical configuration properties (Niagara references, speed values), either force-set them in
BeginPlay()or hard-code the path in the constructor viaConstructorHelpers::FObjectFinder. - Set flight velocity directly first:
AddMovementInputfits the character movement framework better, but is limited byMaxAcceleration; directVelocitysetting feels sharper for fast acceleration. - FOV must go through
PlayerCameraManager: setting thePlayerControllerFOV directly is overridden by the camera component. - Stopping movement must happen immediately on exiting the transformation: otherwise the character keeps surging forward from inertia, and the feel is damaged.
- Niagara trails need world space + Inherit Velocity: in local space, particles have no own velocity and no trail forms.
- A complete recompile is required after editing
.h: new UPROPERTY/UFUNCTION members are reflection-structure changes that Live Coding cannot hot-swap.
Migration note. The current implementation lives in the standalone test project Test_02; to migrate TransformBase into the CultivatingImmortality_RPG main project, also migrate BP_Projectile_Ice and its Niagara asset references, and replace TEST_API with the main project module's API macro.