Singletons in Unity3D

[tweetmeme source=”neoRiley” only_single=false]Here are many different ways of doing singletons in Unity3D – 1) the usual way, 2) the “self contained” way and 3) the quick and dirty way 4) for you c# folks, the accessor way.

1. The Usual Way

The usual way is to have a static “GetInstance()” method on the class  that’s attached to a GameObject in the IDE, and check for an instance.  If it exists, pass it back.  If it doesn’t, return a Debug.LogWarning error about how they need to have a GameObject with the class attached to it.

public class MyClass
{
	private static MyClass instance;
	public static MyClass GetInstance()
	{
		if (!instance)
		{
			instance = GameObject.FindObjectOfType(typeof(MyClass));
			if (!instance)
				Debug.LogError("There needs to be one active MyClass script on a GameObject in your scene.");
		}

		return instance;
	}
}

2. The “self contained” way

At one point in the Trench Run game, I realized my scene was filled with quite a few GameObjects JUST for my classes. So, I developed the “self contained” singleton.  If it doesn’t find an instance, it creates its own GameObject, attaches the class instance to it via AddComponent() bingo, no need to create a GameObject in the IDE and clutter up your scene at design time.

public class Logger : MonoBehaviour
{
	private static Logger instance;
	private static GameObject container;
	public static Logger GetInstance()
	{
		if( !instance )
		{
			container = new GameObject();
			container.name = "Logger";
			instance = container.AddComponent(typeof(Logger)) as Logger;
		}
		return instance;
	}
}

3) The quick and dirty way

The quick and dirty way is simply that – setup a public static property for the instance, initialize in the Awake() method, attach to a GameObject at design time, done. In code, it’s a little more direct now with:

MyClass.instance.DoSomething();

The setup:

public class MyClass
{
	public static MyClass instance;
	public void Awake()
	{
		MyClass.instance = this;
	}
}

It’s been noted in ActionScript that accessing another method outside of the class you’re in is slower than accessing a property.  I have no idea if this is the case with Unity ( I seriously doubt it ), but with my optimization nightmares in Flash over the years, I’m usually doing #3.  Some habits just never go away (or paranoia for that matter)

Enjoy!

[**** UPDATED ****]

4. Accessor

The #1 and #2 examples above could benefit from using an accessor rather than a method – Thanks to Cliff Owen for the tip on this

public class MyClass
{
	private static MyClass _instance;
	public static MyClass Instance
	{
		get
		{
			if (!_instance)
			{
				_instance = GameObject.FindObjectOfType(typeof(MyClass));
				if (!_instance)
				{
					GameObject container = new GameObject();
					container.name = "MyClassContainer";
					_instance = container.AddComponent(typeof(MyClass)) as MyClass;
				}
			}

			return _instance;
		}
	}
}

Then, you’d just as simply as the quick and dirty way access it with:

MyClass.Instance.DoSomething();
    • Richard Adams
    • May 9th, 2011

    Just a quick note as well.. If you’d like your singleton to remain between scene loads just add:

    “DontDestroyOnLoad(container);”

    Just after you create it. This prevents Unity from destroying it and means you can use it to store data between scenes.

  1. Also just a quick note:
    Singleton usually requires that only one instance of an object exists.
    So instead of using “Object FindObjectOfType(t)” use

    “Object[] FindObjectsOfType(t)”

    and check if the resulting array.Length is > 1. If so, throw an exception, destroy the surplus objects or do something else.

    • Danny
    • February 21st, 2013

    hey, thanks for this! when I use method 1, I create a game object, add component>new script> CSharp, than paste the code in. I get these errors:
    error CS0023: The `!’ operator cannot be applied to operand of type `MyClass’
    error CS0029: Cannot implicitly convert type `UnityEngine.Object’ to `MyClass’
    error CS0023: The `!’ operator cannot be applied to operand of type `MyClass’

    whats goin on?
    Thanks!

    • Hey Danny, can you paste the entire class here to see what might be wrong? Need to see the code😉

      Thanks man!

        • Danny
        • February 21st, 2013

        wow fast reply, thanks. Yea I just put the code into the assets folder without attaching to a game object and it works. sorry… just getting started with c#, coming from python

      • Danny
      • February 21st, 2013

      i just put the scripts in the assets, not attached to a gameobject, and it works. Sorry, bad question!

    • Teleias
    • February 23rd, 2013

    :X I have the same problem as Danny (compiler errors), but his solution doesn’t seem to work.
    I have the script unattached to any gameObject.
    What am I messing up on? Same errors he reported. I’m using basically copypasta of the Accessor method.
    Thanks in advance.

  2. Thank you! Great info. Works perfectly. In my simple game state manager I have used:


    public class Singletone {
    protected Singletone() {}
    private static Singletone _instance = null;

    public static Singletone Instance { get {
    return Singletone._instance == null ?
    new Singletone() : Singletone._instance;
    } }
    }

    Didn’t see the need of using ancestor if constructor can be protected internally.

  1. May 11th, 2011

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s