Remember all the cheat codes you could use in old-school games back in the day? Remember the Konami cheat code? Ever wonder how you could add cheat codes to your own games?
Adding cheat codes to your game is a great way to leave your imprint. Think easter eggs, but even more secretive.
In this tutorial we’re going to see how to add keystroke driven cheat codes to a game built with Unity and C#. While the Konami cheat code will be the basis of this example, a lot of the logic and ideas can be applied to other aspects of your game.
To get an idea of what we want to accomplish, take a look at the following animated image:
In the above image, each keystroke is added to the history of keystrokes and displayed on the screen. If we happen to press the key combination “up, up, down, down, left, right, left, right, b, a” the Konami cheat code will be triggered. In our example it doesn’t do anything other than display on the screen, but you could do something like increasing the score, giving more lives, or something else.
There are a few ways to accomplish this task in Unity, but I’m going to demonstrate two different ways as well as their advantages or disadvantages.
We’re first going to take a look at the OnGUI
method that is baked into Unity. If you’ve never seen it, the method would look something like this:
void OnGUI() {
Event e = Event.current;
if(e.isKey && e.type == EventType.KeyUp) {
Debug.Log(e.keyCode.ToString());
}
}
You can add the above method to any script that extends MonoBehaviour
and in the above example the keycode will be printed assuming that it is a KeyUp
event and that it is a key and not a mouse click or something else.
While it is super convenient to be able to determine which key was pressed in only a few lines of code using the OnGUI
method, it’s not without potential problems. The largest of the problems being that the OnGUI
method could be executed up to two times per frame. This is not good for us because it means that numerous events could be registered even if we only intended on one.
To be clear, there are scenarios where if you push the “UpArrow” key, it could get registered as you pushing it twice. In the example of cheat codes where the key combination is important, having this variable amount of keystrokes per frame won’t work.
Let’s take a look at another way to capture specifically which keys were pressed by the user. In this alternative, we’ll be making use of the Update
method and some loops.
Let’s look at the function we can use for detecting which key was pressed:
private KeyCode DetectKeyPressed() {
foreach(KeyCode key in Enum.GetValues(typeof(KeyCode))) {
if(Input.GetKeyDown(key)) {
return key;
}
}
return KeyCode.None;
}
When executed, the DetectKeyPressed
function will loop through all of the potential key codes to see if you’re pressing one of them. If you are, return the keycode for the next step in our pipeline.
So the problem with this is that you have to loop through all the potential keycodes every frame. There aren’t too many of them to stress out modern computers and devices, but it could become a bottleneck in your game if you’re not careful.
With the information and the DetectKeyPressed
function in mind, we can use it in our Update
method like this:
void Update() {
KeyCode keyPressed = DetectKeyPressed();
Debug.Log(keyPressed);
}
From a code length and readability perspective, this way of detecting user input isn’t too different from the OnGUI
way. You just have to evaluate which of the tradeoffs and benefits work the best for your use-case.
Now that we have a way to capture keystrokes from the user, we can use that information to implement cheat codes in our game.
I won’t be going into a deep-dive on how to develop with Unity, so make sure you have the following in your scene for this example to be successful:
We’ll use game objects with the Text
component to show our keystroke history or the cheat code that was entered into the game. The Controller
game object will be empty with the exception that it contains a script attached to it.
So now that we have our basic game objects with various components attached to them in our scene, let’s create a script that will be our controller for the scene. Create a new C# script named Controller.cs with the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using UnityEngine.UI;
public class Controller : MonoBehaviour {
public Text keyStrokeText;
public Text cheatCodeText;
private List<string> _keyStrokeHistory;
void Awake() {
_keyStrokeHistory = new List<string>();
}
void Update() {
KeyCode keyPressed = DetectKeyPressed();
AddKeyStrokeToHistory(keyPressed.ToString());
keyStrokeText.text = "HISTORY: " + GetKeyStrokeHistory();
if(GetKeyStrokeHistory().Equals("UpArrow,UpArrow,DownArrow,DownArrow,LeftArrow,RightArrow,LeftArrow,RightArrow,B,A")) {
cheatCodeText.text = "KONAMI CHEAT CODE DETECTED!";
ClearKeyStrokeHistory();
}
}
private KeyCode DetectKeyPressed() {
foreach(KeyCode key in Enum.GetValues(typeof(KeyCode))) {
if(Input.GetKeyDown(key)) {
return key;
}
}
return KeyCode.None;
}
private void AddKeyStrokeToHistory(string keyStroke) {
if(!keyStroke.Equals("None")) {
_keyStrokeHistory.Add(keyStroke);
if(_keyStrokeHistory.Count > 10) {
_keyStrokeHistory.RemoveAt(0);
}
}
}
private string GetKeyStrokeHistory() {
return String.Join(",", _keyStrokeHistory.ToArray());
}
private void ClearKeyStrokeHistory() {
_keyStrokeHistory.Clear();
}
}
In the above example I am choosing to not use the OnGUI
approach as I didn’t get the results I was looking for.
So let’s break down what’s happening, starting with the Awake
method:
void Awake() {
_keyStrokeHistory = new List<string>();
}
For most cheat codes to be successful, we need to be able to track any number of keystrokes made. For this example, we’re going to store every keystroke in a List
variable. The reality is that we aren’t going to store every keystroke, but we could if we wanted to.
We’ve already seen the DetectKeyPressed
method, but we haven’t seen how to add the keystrokes to our history. This is where the AddKeyStrokeToHistory
method comes in:
private void AddKeyStrokeToHistory(string keyStroke) {
if(!keyStroke.Equals("None")) {
_keyStrokeHistory.Add(keyStroke);
if(_keyStrokeHistory.Count > 10) {
_keyStrokeHistory.RemoveAt(0);
}
}
}
When we attempt to add to the history we check to make sure it isn’t the None
keystroke which pops up occasionally. If it’s not, we push the keystroke into the list and then check to see our list size. If our size exceeds our magic number, then we start removing history from the front of the list which represents the oldest keystrokes.
We’re going to need to be able to check what our keystroke history looks like, so we can do that with the GetKeyStrokeHistory
method:
private string GetKeyStrokeHistory() {
return String.Join(",", _keyStrokeHistory.ToArray());
}
Rather than doing something complicated, I just convert the list into a string delimited by the comma character. This dumps the entire list, but your logic might be different if your cheat codes have various combination sizes. In your circumstance you might want to return the first few keystrokes or the last few keystrokes.
If you look back at the Update
method we can compare the keystroke history with a cheat code and if it matches, we can do something magical!
You just saw two of many possible ways to implement cheat codes into your Unity game. While the premise of this example was cheat codes, the keystroke capturing logic can be applied to different scenarios as well.
To keep your cheat code logic isolated from player logic, enemy logic, or something else, I find it best to keep the logic in the controller for your scene. You don’t have to do it this way, but I personally find it to keep things clean and organized.
You can find a video version of this tutorial below: