How to implement cheat codes

I don’t want to go “console route” for inputting cheat codes. I’d like something like e.g. in first Doom where there is no visible or audible feedback until cheat is correctly entered. How would I go about that?

The easiest way to implement Doom-like cheat codes would be something along the lines of having a script on a Game Object with code like this:

private string[] cheatCode;
private int index;

void Start() {
	// Code is "idkfa", user needs to input this in the right order
	cheatCode = new string[] { "i", "d", "k", "f", "a" };
	index = 0;	
}

void Update() {
	// Check if any key is pressed
	if (Input.anyKeyDown) {
		// Check if the next key in the code is pressed
		if (Input.GetKeyDown(cheatCode[index])) {
			// Add 1 to index to check the next key in the code
			index++
		}
		// Wrong key entered, we reset code typing
		else {
			index = 0;	
		}
	}
	
	// If index reaches the length of the cheatCode string, 
	// the entire code was correctly entered
	if (index == cheatCode.Length) {
		// Cheat code successfully inputted!
		// Unlock crazy cheat code stuff
	}
}

Yet another version.

Based on @mattssonon but I find this a bit easier to setup and use. Enjoy!

It makes use of UnityEvent to being able to pick any public function. And lets you pick any KeyCode instead of just plain strings.

using UnityEngine;
using UnityEngine.Events;

public class CheatInput : MonoBehaviour
{
    public KeyCode[] CheatCode;
    public UnityEvent CheatEvent;
    public float AllowedDelay = 1f;

    private float _delayTimer;
    private int _index = 0;

    void Update()
    {
        _delayTimer += Time.deltaTime;
        if (_delayTimer > AllowedDelay)
        {
            ResetCheatInput();
        }

        if (Input.anyKeyDown)
        {
            if (Input.GetKeyDown(CheatCode[_index]))
            {
                _index++;
                _delayTimer = 0f;
            }
            else
            {
                ResetCheatInput();
            }
        }

        if (_index == CheatCode.Length)
        {
            ResetCheatInput();
            CheatEvent.Invoke();
        }
    }

    void ResetCheatInput()
    {
        _index = 0;
        _delayTimer = 0f;
    }

    public void Cheat()
    {
        Debug.Log("CHEAT ACTIVATED");
    }
}

Here is my implementation. I was very much inspired by GTA San Andreas cheat system, wich has many different cheats, with some of them activating the same effect in the PC version. It has configurable max delay between cheat keystrokes. Although @Shaolin-Dave approach was much more simple, very flawed implementation but good idea, shows me that sometimes I overcomplicate! I tried to comment to make it as clear as possible. But anyway this is easily scalable.

using UnityEngine;
using System;
using System.Collections.Generic;

public class Cheats : MonoBehaviour {
    private readonly float MAX_DELAY = 1f;

    // (cheat_code, effect_id), add as many codes as you like, with any effect id you like, in any order you like!
    // cheat codes only allow characters from a to z though, no spaces, nor symbols, nor numbers
    private readonly Tuple<string, int>[] cheats = new Tuple<string, int>[] {
        Tuple.Create("chucknorris", 2),
        Tuple.Create("explosionman", 0),
        Tuple.Create("blackhole", 1),
        Tuple.Create("funkyattractor", 1),
        Tuple.Create("godmode", 2),
        Tuple.Create("smiteandignite", 0)
    };

    private List<Tuple<string, int>> possibleCheats = new List<Tuple<string, int>>();
    private List<int> indexesToRemove = new List<int>();
    private int currentCheatCharIndex = -1;
    private float currentDelay = 0f;

    void Update () {
        // check if keystroke timed out
        if (currentDelay > MAX_DELAY) {
            Restart();
        }
        currentDelay += Time.deltaTime;
        if (Input.anyKeyDown) {
            // if currently entering cheat
            if (possibleCheats.Count > 0) {
                bool typedTheNextChar = false;
                // check if the keystroke is the next char in every currently possible cheat
                // iterate through the list backwards because we need to remove elements from higher to lower index
                for (int i = possibleCheats.Count - 1; i >= 0; i--) {
                    // Clamp to allow only keycodes from a - 1 (96) to z + 1 (123) (to avoid exceptions on extreme keycodes)
                    if (Input.GetKeyDown((KeyCode)Mathf.Clamp(possibleCheats*.Item1[currentCheatCharIndex], 96, 123))) {*

typedTheNextChar = true;
if (currentCheatCharIndex == possibleCheats*.Item1.Length - 1) {*
Cheat(possibleCheats*.Item2);*
Restart();
// return here to avoid the bug where the last keystroke of a successful cheat counts as the first keystroke in another cheat (were applicable)
return;
}
} else
// this keystroke wasn’t the next in this cheat so we will remove it from possible cheats
indexesToRemove.Add(i);
}
// if keystroke was the next one in at least one of the currently possible cheats
if (typedTheNextChar) {
currentDelay = 0f;
currentCheatCharIndex++;
// discard cheats were keystroke was not the next one
foreach (int i in indexesToRemove)
possibleCheats.RemoveAt(i);
indexesToRemove.Clear();
} else
Restart();
}
// if NOT currently entering cheat
if (possibleCheats.Count == 0) {
for (int i = 0; i < cheats.Length; i++) {
// check if player stroke the first character of any cheat so we can start processing the rest of keystrokes
if (Input.GetKeyDown((KeyCode)Mathf.Clamp(cheats*.Item1[0], 96, 123))) {*
possibleCheats.Add(cheats*);*
currentCheatCharIndex = 1;
currentDelay = 0f;
}
}
}
}
}

void Cheat(int effect) {
switch (effect) {
case 0:
print(“Explosion!”);
break;
case 1:
print(“Black hole!”);
break;
case 2:
print(“God mode!”);
break;
}
}

private void Restart() {
currentCheatCharIndex = -1;
indexesToRemove.Clear();
possibleCheats.Clear();
}
}

nothing wrong with matts answer i just wrote this for my game and i thought i would share. it limits the time between keystrokes so it has to be typed adjustably fast. just just reminded me of old school gaming.
this code works with an x box controller too:

	float quickness;
	String cheater;
	int ii;
	void Update () {
		ii = 9;
		while(ii>0){ii--;
			if (Input.GetKeyDown ("joystick 1 button " + ii)) {

				cheater=cheater+""+ii;
				quickness=0.8f;

			}
			}

		if (Input.inputString != "") {
			cheater = cheater + Input.inputString;
            quickness = 0.8f;// <---time delay between buttons
				}

		if (quickness >= 0) {
						quickness += -Time.deltaTime;
						if (quickness < 0) {
		print ("user is attempting cheat code: "+cheater);
		if (cheater == "boom") {print ("blow stuff up something here");}
		if (cheater == "allweapons") {print ("blow up everyone here");}
				if (cheater == "funkychicken") {print ("i think you get the point");}
		if (cheater == "001133") {print ("i pushed A A B B Y Y on my controller");}

					cheater="";}}}

I just threw this together so you might need to tweak it (i.e. I didn’t confirm the keycodes). This example would start the game when the player presses “Enter” on the keyboard. Normally they have 3 lives, but if they enter the infamous “Konami Code”, they get 30 lives:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class KonamiCode : MonoBehaviour {

	private String inputString;

    void Update ()  {
        if (Input.GetKeyDown(KeyCode.UpArrow)) {
            inputString += 'U';
        } else if (Input.GetKeyDown(KeyCode.LeftArrow)) {
            inputString += 'L';
        } else if (Input.GetKeyDown(KeyCode.DownArrow)) {
            inputString += 'D';
        } else if (Input.GetKeyDown(KeyCode.RightArrow)) {
            inputString += 'R';
        } else if (Input.GetKeyDown(KeyCode.A)) {
            inputString += 'A';
        } else if (Input.GetKeyDown(KeyCode.B)) {
            inputString += 'B';
        } else if (Input.GetKeyDown(KeyCode.Enter)) {
            if (inputString.endsWith('UUDDLRLRBA')) {
                StartGameWithLives(30);
            } else {
                StartGamesWithLives(3);
            }
        } 
	}
}

Some perks to doing it this way, it’ll allow for starting over because it only checks the end of the string. If they mess up the code three times but then get it right on the last one, it’ll still work.
Also, you can easily add codes. Just add a new “endsWith” condition inside the block where “Enter” is pressed.
There’s all sorts of tweaks you can make to this. I’ve also built off of this to create a “Street Fighter”-style special moves input script.

I know that the original post states that they don’t want to use a console, but as this post appears on the first page of Google when you search for “Unity Cheat Console” I thought I would post this answer to help those that may be looking for a console based solution instead:

I would recommend our new Developer Console asset for this: >Developer Console | GUI Tools | Unity Asset Store

It allows you to turn any public, non-public, static or non-static method into a console command which you can invoke at runtime by simply typing it’s name. This also works with parameters and allows you to specify a gameobject as the target.

With some slight modifications I’m sure you could make the console invisible to behave the way you want in the original post, this asset would simply handle all of the complicated backend stuff for you.

It also allows you to view all debug messages in builds, including stacktraces and timestamps, and allows you to collapse duplicates much like Unity’s console. It also allows you to specify a custom file to save all debug messages to in an easy to read format.

Check this out here

if (correctness >= 6)
{
if (correctness < 7)
{
if (Input.GetKeyDown(“right”))
{
correctness = correctness + 1;
Debug.Log(correctness);
}
}
}
if (correctness >= 7)
{
if (correctness < 8)
{
if (Input.GetKeyDown(“left”))
{
correctness = correctness + 1;
Debug.Log(correctness);
}
}
}