Menu
CoddyTech

The Singleton

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

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

Meteors rain down. The Spawner drops a Meteor from a prefab every 1.5 seconds, the arrows move the Player, and the GameManager counts a catch with MeteorCaught() and a meteor that hits the ground with MeteorLanded(). Those scripts are ready.

The Meteor script reports through its game field, but the meteors come from a prefab, so game is empty and every report fails. Fix it with a singleton:

  • In GameManager.cs, add a public static field Instance of type GameManager and set it to this script in Awake.
  • In Meteor.cs, delete the game field and report through GameManager.Instance instead.

Press Play, catch a few meteors and miss a few, 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;
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Building Real Games