When you’re creating a game, you have to play it again and again, repeat some scenarios or create new ones. Also, you have to do it fast, because if any kind of scenario requires from you playing your game or any level from the beginning just to get the desired result, you’re wasting your time doing so. To solve that issue, you should cheat. In a positive way of course! And to do that, you need a game cheats subsystem.
In-game cheats are very old aspect of many games out there on the market. These exist to help developers and testers to test the game and are left in the final production mostly because they can add value to the game. Removing already implemented cheats may compromise the product stability, because this requires another change in the code. There are also some cheats that were implemented as Easter eggs! The best known cheat code that is used as an Easter egg is the Konami Code. You can activate this one even on some websites!
Usually you won’t find out how to use cheats in the game’s manual, because the game authors don’t want you to play using the cheats from the very beginning. Yet you can find cheat codes in the paper magazines or on the Internet.
Implementing game cheats subsystem
Here we will talk about how to implement easy game cheats subsystem that will work on PC and mobile devices. The main requirement is that it should work without using a keyboard. We will treat touch and mouse inputs as equal to make things simpler. Then we have to create any type of GUI. For this task we will use old, but still usable IMGUI. So, let’s start!
Activating cheat codes list
Let’s make it easy to activate the cheat codes list, but not as something that can be done by accident. The list should be activated if you touch/click top-right screen corner 5 times within 2 seconds.
using UnityEngine; using System.Collections; using System; public class Cheats : MonoBehaviour { // Activate corner area size by screen width percentage public float ActivateAreaSize = 0.1f; // How many clicks the player should do before cheats list will be visible public int ClicksCount = 5; // How many seconds player have to click/touch the screen public float WaitTime = 2; private float[] _clickTimes; private int _clickTimesIndex; private bool _active = false; void Start() { // create clicks array and reset it with float.MinValue _clickTimes = new float[ClicksCount]; ResetClicks(); } private void ResetClicks() { for (int i = 0; i < ClicksCount; i++) { _clickTimes[i] = float.MinValue; } } void Update() { // check for click or touch and register it if (CheckClickOrTouch()) { // click will be registered at time since level load _clickTimes[_clickTimesIndex] = Time.timeSinceLevelLoad; // each next click will be written on next array index or 0 if overflow _clickTimesIndex = (_clickTimesIndex + 1) % ClicksCount; } // check if cheat list should be activated if (ShouldActivate()) { _active = true; ResetClicks(); } } // checks if cheat list should be activated private bool ShouldActivate() { // check if all click/touches were made within WaitTime foreach(float clickTime in _clickTimes) { if (clickTime < Time.timeSinceLevelLoad - WaitTime) { // return false if any of click/touch times has been done earlier return false; } } // if we are here, cheat should be activated return true; } // returns true if there's click or touch within the activate area private bool CheckClickOrTouch() { // convert activation area to pixels float sizeInPixels = ActivateAreaSize * Screen.width; // get the click/touch position Vector2? position = ClickOrTouchPoint(); if (position.HasValue) // position.HasValue returns true if there is a click or touch { // check if withing the range if (position.Value.x >= Screen.width - sizeInPixels && Screen.height - position.Value.y <= sizeInPixels) { return true; } } return false; } // checks for click or touch and returns the screen position in pixels private Vector2? ClickOrTouchPoint() { if (Input.GetMouseButtonDown(0)) // left mouse click { return Input.mousePosition; } else if (Input.touchCount > 0) // one or more touch { // check only the first touch Touch touch = Input.touches[0]; // it should react only when the touch has just began if (touch.phase == TouchPhase.Began) { return touch.position; } } // null if there's no click or touch return null; } void OnGUI() { if (_active) { // display cheats list here... } } }
I know that this is quite a lot, but this is the basic implementation. It will:
- Listen for all clicks and touches
- Check if a click/touch has been done within the desired screen area.
- Check if last 5 clicks have been done within the desired timespan.
And it is configurable! Yet what is missing here, is the GUI code and the cheat activation code.
void OnGUI() { if (_active) { DisplayCheat("Close Cheat Menu", () => _active = false); DisplayCheat("Test Cheat 1", () => Debug.Log("Test cheat Activated!")); DisplayCheat("Inverse Gravity", () => Physics.gravity = -Physics.gravity); } } private void DisplayCheat(string cheatName, Action clickedCallback) { if (GUILayout.Button("Cheat: " + cheatName)) { clickedCallback(); } }
Now this is really simple. Game cheats are displayed as clickable buttons. If the button is pressed, the callback delegate is executed. The first cheat is a “cheat” that will close the game cheats list. Now, if you click 5 times in the top-right corner, the cheat list will become visible.
And if you were wondering if it works… 🙂
The package
Feel free to download, and use however you want, the package that includes the script from above and a test scene. The package has been prepared with Unity 5.3.0, so please be sure to import it using the mentioned Unity version or a newer one.