Menu
CoddyTech

The Singleton

Part of the Building Real Games section of Coddy's Unity journey. Lesson 13 of 60.

An Inspector reference needs something to drag onto. Enemies that a spawner makes during the game come from a prefab, and a prefab can only point at assets and at its own parts, never at an object in a scene, so their GameManager field is empty. The usual answer is a singleton: the GameManager stores itself in a field that every script can reach through the class name.

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    private int kills;

    void Awake()
    {
        Instance = this;
    }

    public void EnemyDown()
    {
        kills++;
        Debug.Log("Kills: " + kills);
    }
}
// Enemy.cs, on the enemy prefab
public void Die()
{
    GameManager.Instance.EnemyDown();
    Destroy(gameObject);
}

static means the field belongs to the class, not to an object. Each GameManager object would get its own kills, but there is only one Instance in the whole game, and you reach it with the class name: GameManager.Instance. Any script can read it, an enemy spawned a minute ago included, with no field of its own to fill in.

The manager sets Instance = this; in Awake, where this is the script itself. Unity runs every Awake in the scene before any Start, so other scripts can use GameManager.Instance from their Start on. A second GameManager in the scene would overwrite Instance with itself; the Scenes and Levels chapter shows how to stop that.

challenge icon

Challenge

Easy

Let the meteors reach the GameManager through a singleton.

  1. In GameManager.cs, add public static GameManager Instance; and an Awake() with Instance = this;.
  2. In Meteor.cs, delete the game field and call GameManager.Instance.MeteorLanded() and GameManager.Instance.MeteorCaught() instead.

Press Play and catch a meteor: Caught: 1 shows, with no errors in the Console. Then Check.

Try it yourself

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    public TMP_Text caughtText;
    public TMP_Text shieldText;
    private int caught;
    private int shield = 3;

    public void MeteorCaught()
    {
        caught++;
        caughtText.text = "Caught: " + caught;
    }

    public void MeteorLanded()
    {
        shield--;
        shieldText.text = "Shield: " + shield;
    }
}

All lessons in Building Real Games

Practice on your own: Unity playground