The singleton design pattern exists to palliate to some design flaws in a static class, namely memory allocation. In a standard code, you would have;
private static Singleton instance;
public static Singleton
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
private Singleton() { }
The idea is that memory is allocated only when this class is accessed, unlike a static class that is allocated when the software is started. The private constructor prevents someone else from making an instance, so you can only have access to an instance by it’s public property. On top, you can actually destroy a singleton, unlike a static class.
The idea of having a single instance of something is still quite useful and can prevent unwanted behaviour from occuring. For example, you would want only one script handling save games! Many doing the same job at the same thing could kill a save game.
However, it wouldn’t work in Unity for class deriving from MonoBehaviour or ScriptableObject because of the factory working behind the scene. Those cannot be static. Basically, it’s Unity that creates its own instances. Or as you know, you can put many instances of a MonoBehaviour on many GameObjects. Since MonoBehaviour are created when you place them on a GameObject, you do not have access to the constructor, therefore you enforce uniqueness at a different time.
private static Singleton instance = null;
public static Singleton Instance
{
get { return instance; }
}
private void Awake()
{
// If instance already exist, destroy ourself.
if (instance != null instance != this)
{
Destroy(gameObject);
return;
}
// No instance exist yet? We are it.
instance = this;
// This line exist so that the Singleton would persist between scene loads.
// Not all singletons needs that.
DontDestroyOnLoad(gameObject);
}
as a side note. the issue you may have with multiple instances is with dontdestroyonload. so when the singleton instance is created in a scene and the scene is reloaded the same object is also created again and the old one not destroyed so you end up with more than one. thats why you have to check if there is already an instance.
on the other hand i find it a bit brute to destroy the whole gameobject with the duplicated instance as there can be many scripts on it. so either you make sure gameobjects with singleton scripts have no other scripts attached or you should use destroycomponent.
also a note i’m not sure about that destroy(gameobject) destroys it at the end of the frame. this means in the meantime you could have two objects lying around but the second is not referenced. but when it executes actions itself (fe in update) these could still happen. i don’t know if remove component works instantly.
static data is persisted between plays (in editor) so you should keep care about initialization stuff that you properly reset it. you could utilize onenable/disable for this these are called when unity compiles the scripts and i think also when hitting play. so it can be a bit tricky to work with static data in the editor what could lead to unexpected behavior.