How to Implement a Game Cheats Subsystem Within Unity3D

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!

konami code
Konami Code

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:

  1. Listen for all clicks and touches
  2. Check if a click/touch has been done within the desired screen area.
  3. 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.

game cheats list

And if you were wondering if it works… 🙂

inverse gravity cheat

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.

related
AdvancedTips
Profiling Unity Application with Profiler Samples
The Unity Profiler Samples is something that most of Unity users are unaware of. Yet it can...
0
IntermediateTips
Optimize yourself! [Part 2]
Things you can do better in Unity! This is the second part of our tips list, that can help...
0
AdvancedTips
Rendering custom GUI on Scene view
If you're using assets from the Asset Store then most probably you realized that some scripts...
3
Call The Knights!
We are here for you.
Please contact us with regards to a Unity project below.



The Knights appreciate your decision!
Expect the first news soon!
hire us!