01 · Capture
One runtime subsystem records input and world state together.
A GameInstanceSubsystem owns the recording lifecycle and samples on the core ticker. Each frame stores delta time, tracked actor transforms, and Enhanced Input values for Boolean, 1D, 2D, and 3D actions.
Weak actor references keep the recorder from extending object lifetimes, while a clip object provides a compact boundary for frame data, duration, map identity, and future event tags.
02 · Playback
Ghost motion remains smooth even when the source is frame-based.
A reusable ActorComponent binds to a clip and exposes play, pause, stop, looping, playback speed, and start-time controls. During playback it advances a playhead, finds the surrounding samples, and blends transforms before applying them to the ghost actor.
- Transform interpolation prevents visible frame stepping
- Loop and speed controls support testing and replay variation
- Blueprint-callable APIs keep the C++ system accessible to designers
const FIRGRActorFrame* Prev = PrevActors.FindByPredicate(
[this](const FIRGRActorFrame& Frame) {
return Frame.ActorPath == ActorTrack;
}
);
if (Prev)
{
const float Alpha =
(Time - Acc) / Clip->Frames[i].DeltaTime;
FTransform Blended;
Blended.Blend(
Prev->Transform,
Cur->Transform,
FMath::Clamp(Alpha, 0.f, 1.f)
);
OutXform = Blended;
}Playback finds the two samples around the current playhead and blends their transforms, so recorded frame data produces a smooth ghost trajectory.
03 · Current boundary
The prototype proves capture and replay before persistence.
The repository separates runtime and editor modules and includes a Blueprint function library plus a generated circular test clip. File save and load are deliberately still stubs, so the next milestone is durable clip serialization rather than a claim of finished production tooling.