For it to work though I believe it cannot be attached to any game object, which I am accustomed to doing.
Is there any reason why you would want to attach a singleton class to a game object?
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
I don’t think this is possible, in the sense that MonoBehaviours are intended to be part of the scene, which means that they can be instantiated and duplicated outside of the singleton pattern.
That said, several of my game objects hold managers that are MonoBehaviours in order to hook into the Start() and Update() functions. While I don’t enforce the singleton pattern on these managers, I do have code that looks like this inside of the script:
public class GameManager : MonoBehaviour
{
private static GameManager sManager = null;
public static GameManager Instance()
{
if (sManager = null)
sManager = FindGameManager();
return sManager;
}
}
so that other systems can just use
GameManager.Instance.DoSomething()
I forget the details of FindGameManager(), or whether you can just assign the this pointer. Not in front of the code right now.
Either way, this may look like the singleton pattern, but it isn’t, because you can still apply the GameManager script on another object. And calls to GameManager.Instance() may become ambiguous. I just make sure I don’t have another GameManager script in my hierarchy.
I do it all the time and so does Unity (see UNet). Often, you want a manager that should still run Monobehaviour stuff, such as awake, setup, even update.
Also, it’s sometimes desirable for a singleton to only persist for the lifetime of a given scene. Or for it to contain serialized information. The latter isn’t quite a classic singleton in that it doesn’t create itself as needed, but it is an object that there can only be one of and which can be accessed by an Instance property.
My singleton class derives from MonoBehaviour, and in fact I have hardly any top-level classes which don’t. For the reasons @hippocoder stated plus I love having the Inspector available which allows me to do things which make my life easier.
Adding to @Errorsatz post above, another handy pattern in Unity is a singleton which “spins up” from a Prefab asset, and may optionally do so on a per-scene basis.
Essentially you have a .Instance type static accessor field, and instead of just newing up a GameObject and attaching itself as a component, it Instantiates a particular prefab and gets the instance of itself out of there.
There are a lot of handy use cases that this addresses, such as having singletons that can have their properties modified in the Unity3D and saved as prefab assets, and also having multiple different variations of the prefab.
This is code that I use all the time. All MonoBehaviours that are also Singletons extend this class like so:
public class SMBClass : MonoBehaviourSingleton<SMBClass>
It also enforces the Singleton nature by deleting any objects that come later
public class MonoBehaviourSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance
{
get
{
if (instance == null)
{
GameObject coreGameObject = new GameObject(typeof(T).Name);
instance = coreGameObject.AddComponent<T>();
}
return instance;
}
}
private static T instance;
protected virtual void Awake()
{
if (instance == null)
instance = GetComponent<T>();
else
DestroyImmediate(this);
}
}
Actually, that implementation in the wiki is more error-prone than your short version. With the wiki version, It’s just too easy to introduce bugs that are difficult to track down.