- Home /
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?
Answer by mattssonon · Oct 11, 2013 at 07:50 AM
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
}
}
Thanks! Had vague idea how it would be done, but needed some clarification. $$anonymous$$arking as best answer and upvotting!
If something is helping you, you can thank the person who posted it by upvoting their comment or answer.
Also please don't comment on questions that are many years old, if you do, they will be ressurrected and show on the front page, where they take the place of a new question.
How would I use arrows in this? When I use UpArrow in the string I get the error: "Input key named: UpArrow unknown"
small typo, should be index++ ; Also once unlocked I would suggest to reset the index when unlocked so it does not run infinitely unlocked in update.
Wouldn't this degrade performance with many chest codes? (add different cheat codes to different array and have a index for each of them).
So update will check for each cheat code when a key is down. That's my idea of doing this for multiple cheat codes but I am not sure it's the best one in terms of performance.
Answer by neshius108 · Sep 06, 2018 at 06:27 PM
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");
}
}
Answer by Lagger625 · Sep 12, 2018 at 03:12 AM
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[i].Item1[currentCheatCharIndex], 96, 123))) {
typedTheNextChar = true;
if (currentCheatCharIndex == possibleCheats[i].Item1.Length - 1) {
Cheat(possibleCheats[i].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[i].Item1[0], 96, 123))) {
possibleCheats.Add(cheats[i]);
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();
}
}
Answer by toddisarockstar · Mar 04, 2017 at 10:27 PM
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="";}}}
Answer by Shaolin-Dave · May 14, 2018 at 10:17 PM
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.
omg your approach is simple and clever compared to $$anonymous$$e...
The thing here is, if you keep playing and pressing keys the inputString will keep growing bigger and bigger, wich will cause a growing-over-time waste of memory and CPU resources (related to garbage collection and concatenation of strings using "+" operator).
You should use some other way of keeping track of the last pressed keys.
In this particular case, this code would only be relevant on the title screen. I don't think players would spend that much time there pushing random buttons. In my "Street Fighter"-style application, I had the method consider in the string ended with any special move key combination, execute the proper method if it did, execute a basic attack method if it didn't, and then clear out the string. It was never longer than whatever it gathered in-between punches/kicks. Depending on the application, you can have different methods of controlling the length. A new strategy I just thought of would be a looping coroutine (maybe every 10 seconds or so) that trims the string down to it's last 10 characters (or however many the longest cheat code is).
Your answer
Follow this Question
Related Questions
Cheat Code Box 1 Answer
How to fly with cheat code ? 0 Answers
Game Glitches and Cheat Codes 3 Answers
Problem With Enemy AI 0 Answers
My monster only choose one Target 2 Answers