Scene-Safe Singleton GameManager in Unity

Scene-Safe Singleton GameManager in Unity

When creating a GameManager that needs to be accessed globally, it's common to use the Singleton pattern. However, if your project has more than one scene, you’ll often face the issue of having to manually place a GameManager GameObject in every scene.

To solve this cleanly, you can extend the basic singleton setup for scene-safe behavior.

Singleton Pattern That Survives Scene Changes

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }

    void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject); // Remove duplicate
            return;
        }

        Instance = this;
        DontDestroyOnLoad(gameObject); // Persist across scenes
    }
}

This setup ensures:

  • The GameManager is created only once in the first scene.
  • It persists across scenes using DontDestroyOnLoad.
  • Duplicates in later scenes are destroyed immediately.

However, problems arise when a scene without the GameManager is launched directly (e.g., testing a subscene alone). In such cases, GameManager doesn’t exist, which can lead to NullReferenceException.

Auto-Creating GameManager Using the Resources Folder

To avoid the null reference issue, you can store a GameManager prefab inside the Resources folder and have it load automatically when needed.

Steps to Create the Prefab

  1. Create a GameManager GameObject in the Hierarchy.
  2. Drag it into Assets/Resources to save it as a prefab.
  3. Then delete the GameManager from the Hierarchy.

Add Auto-Loading Code to GameManager.cs

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void AutoCreateSingleton()
{
    if (Instance == null)
    {
        GameObject prefab = Resources.Load<GameObject>("GameManager");
        if (prefab != null)
        {
            _ = Instantiate(prefab);
        }
        else
        {
            Debug.LogError("GameManager prefab not found in Resources folder.");
        }
    }
}

Note: What is [RuntimeInitializeOnLoadMethod]?

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] tells Unity to automatically call the static method right below it before any scene is loaded.

This method must be declared as static, and it will be executed even if there is no GameObject in the scene.

Now, the GameManager will automatically be created if it doesn't exist, keeping your scenes safe from null reference errors.

Summary

  • Basic singleton is fine for single-scene projects.
  • For multi-scene setups, use DontDestroyOnLoad and duplicate checks.
  • To avoid errors in isolated scenes, auto-load the GameManager from Resources.
  • This structure becomes especially useful as your project grows in size and complexity.

Additionally...

If your singleton class, such as GameManager, needs to initialize data specific to each scene, you should not rely on Awake() or Start() methods. These methods are only called once, and will not be invoked again when the scene is reloaded.

In such cases, you must use the SceneManager.sceneLoaded event to set up the necessary data whenever a scene changes. We’ll cover SceneManager.sceneLoaded in more detail in a future post.

Popular posts from this blog

Understanding Arrays as Reference Types in C#

Setting Up a Basic Follow Camera with Cinemachine 3.x

Understanding and Using ? (nullable) in C#