CREATIONAL

Singleton

What is it?

Singleton is a design pattern that makes sure a class has only one instance during the lifetime of the application. This instance can be accessed from different parts of the project through a shared access point.

In Unity, Singleton is commonly used for systems such asGameManager, AudioManager, SceneLoader, or SaveSystem. These are systems that usually need to exist once and be reachable from multiple scripts.

The basic idea is simple: the class stores its own instance in a static variable. When another script needs it, it does not create a new object. Instead, it uses the existing instance.

When is it used?

Singleton is useful when a system should logically exist only once in the whole game. For example, a GameManager can control the overall game flow, an AudioManager can handle sounds, and a SaveSystem can manage save and load operations.

It is also useful for objects that need to survive between scene changes. In Unity, this is usually done with DontDestroyOnLoad.

However, Singleton should not be used for everything. Objects such as players, enemies, bullets, pickups, or UI elements that can have multiple copies should not be Singletons.

Animation

0 / 1 instance
AudioManager.InstanceSceneLoaderUIControllerGameManager

Code

Assets / Scripts / Creational / SingletonSingleton.cs
READ ONLY
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
namespace Patterns.Creational.Singleton
{
    using UnityEngine;

    public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
    {
        private static T _instance;

        public static T Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = FindObjectOfType<T>();

                    if (_instance == null)
                    {
                        GameObject obj = new GameObject(typeof(T).Name);
                        _instance = obj.AddComponent<T>();
                    }
                }

                return _instance;
            }
        }

        protected virtual void Awake()
        {
            if (_instance == null)
            {
                _instance = this as T;
                DontDestroyOnLoad(gameObject);
            }
            else if (_instance != this)
            {
                Destroy(gameObject);
            }
        }
    }
}

Advantages and disadvantages

• Advantages:

  • It provides easy access through a shared instance.
  • It can prevent duplicate manager objects.
  • It can speed up development in small and medium projects.

• Disadvantages:

  • It can create hidden dependencies.
  • It can lead to too much global state.
  • Overusing it can make systems tightly connected.

Tips

In Unity, Singleton setup is usually done inside Awake, because Awake runs before Start. A common structure is to check whether Instance is null.

For managers that need to stay alive between scenes,DontDestroyOnLoad(gameObject) should be used. But it is important to check for duplicates before keeping the object alive.

The execution order of Awake can also cause problems. If another script tries to access the Singleton inside its own Awake, the Singleton may not be ready yet.

Finally, Singleton should be used only for systems that are truly global. For smaller or more local dependencies, Inspector references, events, ScriptableObjects, or dependency injection can often be cleaner solutions.