What is the Singleton Design Pattern?
Using the Singleton Design Pattern in Unity
The singleton design pattern is a commonly used design pattern to ensure that a class is instantiated only once and provides global access to this instance. In game engines like Unity, it is usually used for components such as the Game Manager, Audio Manager, or data loading systems. In this article, we will examine how to implement the Singleton design pattern in Unity with examples.
What is a Singleton?
The Singleton design pattern basically provides two features:
- A class has only a single instance.
- It offers a global access point to this instance.
In Unity projects, by using a Singleton, you can prevent a particular class from being instantiated repeatedly, and can easily access the properties or methods of this class.
Advantages of the Singleton Design Pattern - Global Access:
- Singleton: provides global access to a single object, making your code more readable.
- Performance: Optimizes memory usage by preventing the same object from being instantiated over and over.
- Easy Management: Provides centralized management, so you can control your settings or global state from a single point.
How to Implement Singleton in Unity?
Singletons in Unity are usually implemented as a MonoBehaviour class. The reason is that when added to the scene, singletons run on GameObjects.
Simple Singleton Example
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
public void SomeFunction()
{
Debug.Log("GameManager Singleton is running!");
}
}What is Happening in This Code?
- Instance Variable: With public static GameManager Instance { get; private set; }, we make the Singleton globally accessible.
- Awake Method: The Awake method ensures the Singleton remains as a single instance. If there is already an instance, we destroy the newly created GameObject.
- DontDestroyOnLoad: This method ensures that the object is not destroyed during scene changes.
Usage
Now, you can use the GameManager in another class as follows:
GameManager.Instance.SomeFunction();
Advanced Singleton Implementation
using UnityEngine; public class Singleton: MonoBehaviour where T : MonoBehaviour { private static T _instance; private static readonly object _lock = new object(); public static T Instance { get { lock (_lock) { if (_instance == null) { _instance = (T)FindObjectOfType(typeof(T)); if (_instance == null) { GameObject singletonObject = new GameObject(typeof(T).Name); _instance = singletonObject.AddComponent (); DontDestroyOnLoad(singletonObject); } } return _instance; } } } }
This Generic Singleton eliminates the need to rewrite code repeatedly for different classes. It is enough to just derive your class from Singleton:
public class AudioManager : Singleton{ public void PlaySound() { Debug.Log("Playing sound!"); } }
Things to Consider When Using Singleton
- Testability: Since singletons provide global access, they can be difficult to test. Therefore, in some cases, alternatives like Dependency Injection may be preferred.
- Memory Leak Risk: Since singletons can live across scenes, if not managed properly, they can cause memory leaks.
- Complexity: The Singleton design pattern can be used in simple projects, but excessive use in large projects can lead to code complexity.


Yorum Gönder