Implementing The Command Pattern In Unity
How to achieve replay functionality, as well as undo and redo in Unity by using the command pattern. Use it to enhance strategy and similar games. By Najmm Shora.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Implementing The Command Pattern In Unity
20 mins
- Getting Started
- Understanding the Bot logic
- Understanding the Command Design Pattern
- Moving the Bot
- Implementing the Command Pattern
- Creating the Commands
- Using the Commands
- Running the Game to Test the Command Pattern
- A Closer Look at the Commands
- Implementing Undo and Redo Functionalities
- Handling Edge Cases
- Where to Go From Here?
- Challenge
Implementing Undo and Redo Functionalities
Run the scene one more time and try to reach the green checkpoint.
You might notice that there is no way for you right now to undo a command that you entered, which means that if you made a mistake you cannot go back unless you execute all the commands. You can fix that by adding an Undo and consequently a Redo functionality.
Go back to SceneManager.cs and add the following variable declaration right after the List declaration for botCommands:
private Stack<BotCommand> undoStack = new Stack<BotCommand>();
The undoStack variable is a Stack (from the Collections family) that will store the references to the commands that have been undone.
Now, you will add two methods UndoCommandEntry and RedoCommandEntry for the purposes of Undo and Redo respectively. In the SceneManager class, paste the following code after ExecuteCommandsRoutine:
private void UndoCommandEntry()
{
//1
if (executeRoutine != null || botCommands.Count == 0)
{
return;
}
undoStack.Push(botCommands[botCommands.Count - 1]);
botCommands.RemoveAt(botCommands.Count - 1);
//2
uiManager.RemoveLastTextLine();
}
private void RedoCommandEntry()
{
//3
if (undoStack.Count == 0)
{
return;
}
var botCommand = undoStack.Pop();
AddToCommands(botCommand);
}
Going through this code:
- If the commands are being executed or if the
botCommandslist is empty, theUndoCommandEntrymethod won't do anything. Otherwise, it will push the reference to the very last entered command, onto theundoStack. This also removes the command reference from thebotCommandslist. -
RemoveLastTextLinemethod fromUIManagerremoves the last line of text from the terminal UI so that the UI is consistent with the contents ofbotCommandswhen an undo occurs. -
RedoCommandEntrydoes nothing ifundoStackis empty. Otherwise, it pops off the last command on top ofundoStackand adds it back to thebotCommandslist viaAddToCommands.
Now, you will add keyboard inputs to use these methods. Inside the SceneManager class, replace the body of the Update method with the following:
if (Input.GetKeyDown(KeyCode.Return))
{
ExecuteCommands();
}
else if (Input.GetKeyDown(KeyCode.U)) //1
{
UndoCommandEntry();
}
else if (Input.GetKeyDown(KeyCode.R)) //2
{
RedoCommandEntry();
}
else
{
CheckForBotCommands();
}
- Pressing the key U calls the
UndoCommandEntrymethod. - Pressing the key R calls the
RedoCommandEntrymethod.
Handling Edge Cases
Great — you are almost done! But before finishing, you should make sure of two things:
- If you enter a new command, the
undoStackshould get cleared. - Before executing the commands, the
undoStackshould get cleared.
To do this, first you will add a new method to SceneManager. Paste the following method after CheckForBotCommands:
private void AddNewCommand(BotCommand botCommand)
{
undoStack.Clear();
AddToCommands(botCommand);
}
This method clears the undoStack and then calls the AddToCommands method.
Now, replace the call to AddToCommands inside CheckForBotCommands with the following:
AddNewCommand(botCommand);
Finally, paste the following line after the if statement inside the ExecuteCommands method, to clear the undoStack before execution:
undoStack.Clear();
And you are done! For real this time!
Phew!

Phew!
Save your work. Build and click Play in the editor. Type commands as before. Press U to undo the commands. Press R to redo the undoed commands.

Try to reach the green checkpoint.
Where to Go From Here?
You can download the project materials using the Download Materials button at the top or bottom of this tutorial.
To know more about the design patterns involved in game programming, I strongly recommend checking out Game Programming Patterns by Robert Nystrom.
To learn more about advanced C# techniques, check out the course C# Collections, Lambdas, and LINQ on our website.
Challenge
As a challenge, see if you can reach the green checkpoint at the end of the maze. I have provided the solution below in case you are stuck. It is just one of the many solutions you can arrive at.
[spoiler title="Maze Solution"]
- moveUp × 2
- moveRight × 3
- moveUp × 2
- moveLeft
- shoot
- moveLeft × 2
- moveUp × 2
- moveLeft × 2
- moveDown × 5
- moveLeft
- shoot
- moveLeft
- moveUp × 3
- shoot × 2
- moveUp × 5
- moveRight × 3
[/spoiler]
That's it! Thanks for reading. I hope you enjoyed the tutorial, and if you have any questions or comments, please join the forum discussion below!
Special thanks to the artists Lee Barkovich, Jesús Lastra and sunburn for some of the assets used in the project.
