Action Replay System
Record player input as timestamped frames and replay it at any speed. Use it for ghost racing, replays, AI training data, QA reproduction, or highlight clips.
Structure
ActionRecorder (pure C# instance)
- Adds InputFrame entries to ReplayData when input occurs
ActionPlayer (pure C# instance)
- Plays ReplayData through Tick(deltaTime) and emits OnFrame events
InputFrame (struct)
- Timestamp, ActionKey, Axis, IsPressed
ReplayData (class)
- TotalDuration + List<InputFrame>
Quick Start
1. Record
using AchUtils.ActionReplay;
private readonly ActionRecorder recorder = new();
recorder.StartRecording();
public void OnJumpPressed()
{
recorder.RecordButton("Jump", pressed: true);
// Run real jump logic...
}
public void OnMove(Vector2 axis)
{
recorder.RecordAxis("Move", axis);
}
ReplayData data = recorder.StopRecording();
SaveReplay(data);
2. Replay
private readonly ActionPlayer player = new();
void Update()
{
player.Tick(Time.deltaTime);
}
void PlayGhost(ReplayData data)
{
player.OnFrame += HandleFrame;
player.Play(data, speed: 1f);
}
void HandleFrame(InputFrame frame)
{
switch (frame.ActionKey)
{
case "Jump": ghost.Jump(); break;
case "Move": ghost.Move(frame.Axis); break;
case "Attack": ghost.Attack(); break;
}
}
player.OnCompleted += () =>
{
Debug.Log("Replay completed");
player.OnFrame -= HandleFrame;
};
API
ActionRecorder
bool IsRecording
ReplayData LastRecording
void StartRecording()
ReplayData StopRecording()
void RecordButton(string key, bool pressed)
void RecordAxis(string key, Vector2 axis)
void Record(string key, Vector2 axis = default, bool pressed = true)
ActionPlayer
bool IsPlaying
void Play(ReplayData data, float speed = 1f)
void Stop()
void Tick(float deltaTime)
event Action<InputFrame> OnFrame
event Action OnCompleted
event Action OnStopped
InputFrame
float Timestamp
string ActionKey
Vector2 Axis
bool IsPressed
Playback Speed
player.Play(data, speed: 0.5f); // Slow motion
player.Play(data, speed: 2.0f); // Double speed
Serialization
ReplayData is [Serializable], so it can be saved as JSON.
string json = JsonUtility.ToJson(data);
File.WriteAllText("replay.json", json);
string json = File.ReadAllText("replay.json");
ReplayData data = JsonUtility.FromJson<ReplayData>(json);
Use Cases
| Use case | Description |
|---|---|
| Ghost racing | Replay a best run as a translucent object |
| Replay system | Watch the moments before death |
| AI training data | Use human input for imitation learning |
| Bug reproduction | Reproduce QA input exactly |
| Video clips | Auto-cut highlight moments |
::: warning Networking
Multiplayer replay sync requires a deterministic game loop. Physics-heavy games should drive physics manually, for example with Physics.simulationMode = Script.
:::