The singleton pattern is useful when writing game components like a game manager or localization manager in Unity. I would like to share with you the implementation I am currently using in my project.
Inspiration
While creating my implementation I took inspiration from several sources:
- Localization Manager sample - an approach using the
Awake()
method, which destroys all instances created after the first one. - Unity Community Wiki - this implementation guarantees to create one instance only and is thread-safe thanks to locking.
- Singleton pattern blog post by Jon Skeet - once again I revisited this excellent blog post on implementing singleton pattern in C#, and I warmly recommend it!
Code
Note: This code requires enabling the .NET 4 scripting runtime to access the Lazy<T>
type.
- Open player settings in the Unity Inspector by selecting Edit > Project Settings > Player.
- Under the Configuration heading, click the Scripting Runtime Version drop-down and select .NET 4.x Equivalent. You will have to restart Unity for the change to take effect.
Explanation
My singleton is implemented as a generic class deriving from MonoBehaviour
. This is necessary to have access to the DontDestroyOnLoad
method we call in CreateSingleton
. The type argument should also derive from MonoBehaviour
so that we can use the instance as a component and receive all messages like Awake
, Start
and Update
. When used in a derived class, you pass the concrete type as the type argument. This looks a bit circular when written, but it is basically just saying "class X is a singleton of type X". For the pattern itself, I went with the version using Lazy<T>
suggested by Jon Skeet in his article. The advantage of this is that Lazy<T>
handles the thread-safety out of the box and we don't have to do any locking ourselves. The singleton initialization itself is very straightforward - we create an empty GameObject
, attach our component to it and finally mark it so that it won't be destroyed when new scene is loaded.