This project provides a method of implementing a rewind effect in a game, popularised by games such as Braid.
The rewind ability in this project is made possible due to the Command Pattern, which makes implementing a rewind ability surprisingly easy.
All actions in the scene (including player/enemy movement, deaths, projectile release/movement) are encapsulated as actionable command objects. The base Command class is shown below.
/// <summary> /// Base abstract command. All commands (e.g. movement, attack) should inherit form this class. /// </summary> public abstract class Command { protected Transform character; protected Vector2 dir;
public Command (Transform character = null, Vector3 dir = default(Vector3)) { this.character = character; this.dir = dir; }
/// <summary> /// Perform the action. /// </summary> public abstract void Execute ();
/// <summary> /// Perform the reverse action. /// </summary> public abstract void Undo (); }
Each command has an execute and undo method. For example, implementation of a simple movement command.
public class MovementCommand : Command { private Vector2? undoDir;
public MovementCommand (Transform character, Vector2 dir) : base (character, dir) { }
To reverse the scene (and begin the rewind effect), you simply iterate through the command group in reverse order and execute the commands undo methods.
/// <summary> /// Checks if it is ok to undo and calls the most recent commands undo method. /// The command list is traversed from most recent to first. /// When current command is less than 0 the complete flag is set to true. /// This will stop the rewind process and enable the character to run new commands. /// </summary> protected override void Execute () { if (CancelRequested ()) { Reset (); return; }
foreach (var command in commands[currentGroup].Reverse ()) { command.Undo (); }
commands.RemoveAt (currentGroup);
currentGroup--; if (currentGroup < 0) { Reset (); } }