Singleton usage wherever possible? GAWSANA in Unity?

GAWSANA == Global Access When Singletons Are Not Available.

Hi,

We’re currently in the process of building a prototype to get up to scratch with the process of making a game and I’m just wondering what the best practice is with regards to Singletons. Essentially, would it make sense to make all the classes that should only be used once into a singleton, or is it unnecessary?

At the moment, the GameController (which controls the game state and a few other basic things) is one, but should I do the same for the PlayerController scripts? These are obviously only used once on the player, but is there any need to do this other than to make it easier to reference them on other objects (which would be a nice advantage!)?

I’ve also included the Singleton part of the GameController. Is this adequate? I’ve seen a few versions of ‘Unity singletons’ since and I’m not sure how the code below could cause any issues.

Thanks!

public class GameController : MonoBehaviour
{	
	// Create a singleton - only one instance of this class can be made
	private	static	GameController	_instance	=	null;
	
	public	static	GameController	Instance
	{
		get
		{
			if (_instance == null)
			{
				_instance = GameObject.FindObjectOfType(typeof(GameController)) as GameController;
			}
			
			return _instance;
		}
	}
	
	void Awake ()
	{
		_instance = this;
	}

First, buckle up. This is gonna be a hell of a ride! [\m/][1]

The singleton pattern is indeed, one of the most miss-used and debated pattern amongst all other patterns.

They say it’s evil, its evilness comes from the fact that most people use it because they’re too lazy to pass their references to their classes, and they feel that it’s easier to just have an easy global access to their variables, which smells like static (no need to say how evil statics are, if they’re misused)

You can read all about what the experts have to say about it (which normally, a lot of us including me don’t give a rat ass about lol), but they all circle around:

  • It’s hard to perform tests on singletons.
  • They hide your class dependencies.
  • What if, at some point in the future you decided that you need another reference of your class?

For more info, see [1][2], [2][3].

So does this mean you shouldn’t use a singleton? - You can use the singleton AS LONG AS YOU DON’T MISS-USE IT!

Why do I mean by that? - Well, singletons exist to give you the ability to have only one instance of your object at a time. They’re NOT meant to be used only to provide easy global access. That’s when you miss-use it.

Would it make sense to make all the classes that should only be used once into a singleton, or is it unnecessary?

Well, it’s definitely not a must. But if for some reason you must have only one instance of your class, if you’re 100% sure that you won’t need more than one, and you don’t actually care about the global access (sweet-looking) feature, if you see that your object will live throughout your entire application, then by all means, USE IT! ([DO. IT.][4] Gus tone lol) WITHOUT FEAR (especially from those who scare you away from it for no reason). Otherwise, don’t.

I will tell you of some other alternatives in a second, for now here’s a nice Singleton implementation, taken from the [wiki][5], and modified by me so that if you ever had more than one instance of your gameObject, all the extra instances get destroyed and only one remains:

using UnityEngine;

public class MonoBehaviourSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
	private static object mLock = new object();
	private static T mInstance;
	public static T Instance
	{
		get
		{
			lock (mLock) {
				if (mInstance == null) {
					// try to find it
					T[] instances = FindObjectsOfType(typeof(T)) as T[];

					// couldn't find any object
					if (instances == null || instances.Length == 0) {
						var instanceObj = new GameObject("(Singleton) " + typeof(T));
						mInstance = instanceObj.AddComponent<T>();
						Debug.Log("[Singleton]: An instance of `" + typeof(T) + "` is needed." +
								  " So gameObject `" + instanceObj.name + "` was created" +
								  " with `" + typeof(T) + "` component attached to it");
					}
					else {
						// see if there's more than one, if so, do something about it
						if (instances.Length > 1) {
							Debug.LogWarning("[Singleton]: There is more than one instance of `" +
											 typeof(T) +
											 "` in your scene. Destroying all, keeping only one...");

							for (int i = 1, len = instances.Length; i < len; i++) {
								Destroy(instances*);*
  •   						}*
    
  •   					}*
    
  •   					else if (instances.Length == 1) {*
    
  •   						Debug.Log("[Singleton]: Found only one instance of `" +*
    
  •   								  typeof(T) +*
    
  •   								  "` in `" + instances[0].gameObject.name +*
    
  •   								  "` So singlation successful! :)");*
    
  •   					}*
    
  •   					mInstance = instances[0];*
    
  •   				}*
    
  •   				DontDestroyOnLoad(mInstance); // for preservation of this object through scenes*
    
  •   			}*
    
  •   			return mInstance;*
    
  •   		}*
    
  •   	}*
    
  •   }*
    
  •   public void Ping()*
    
  •   {*
    
  •   	Debug.Log("[Singleton]: `" + this + "` is alive!");*
    
  •   }*
    
  •   protected virtual void Awake()*
    
  •   {*
    
  •   	Ping(); // this is just so that DontDestroyOnLoad gets called on the gameObject that's gonna this script upon waking up - Calling Ping means accessing the singleton instance, doing so calls DontDestroyOnLoad at the end.*
    
  •   }*
    
  • }*
    As you can see what’s nice about this implementation, is that it inherits from MonoBehaviour so you can enjoy coroutines, etc. The other cool thing as I mentioned, is that if more than one instance is found, all die but one. You don’t have to worry about nulls. And it’s also thread-safe.
    USAGE:
    public class GameController : MonoBehaviourSingleton
    {
    // …
    }
    Now from anywhere else you can: GameController.Instance.doStuff(); - If doStuff is called regularly, you could avoid a few keystrokes by introducing a static method in your GameController:
    void static void DoStuff()
    {
    Instance.doStuff();
    }
    Now you can immediately: GameController.DoStuff();
    So far I have no problems using this system whatsoever (From a not-very-long-time usage perspective)
    FURTHER AWESOME REASONS TO USE THE SINGLETON:
    - Everybody is doing it.
    - The singleton pattern makes you
    invincible.
    - Singleton rhymes with “win” (or “fun”
    depending on your accent).
    ([from][6])
    ----------
    Now that we’re done with that, let me introduce you to the first alternative, a new product, a product that will change your life ([it’s beer, huehue hueheu hue][7]): It’s Mr.Fattie’s almighty super awesome immortal Grid system (@Fattie)
    Take a look at it [here][8].
    Now, I was actually intending to open up a large question related to Singletons and this system, but I couldn’t have the time. But since I wanted to do that, I went ahead and made a clean, nice implementation of Mr.Fattie’s system, I renamed it Container which I think is more expressive in terms of the meaning:
  • using UnityEngine;*
  • public static class Container*
  • {*
  •   public static AtlasManager AtlasManager { private set; get; }*
    
  •   public static GameController GameController { private set; get; }*
    
  •   public static InventoryManager InventoryManager { private set; get; }*
    
  •   // insert more stuff here...*
    
  •   public static GameObject HoldAll { private set; get; }*
    
  •   static Container()*
    
  •   {*
    
  •   	HoldAll = SafeFindWithTag(Tags.holdAll);*
    
  •   	Object.DontDestroyOnLoad(HoldAll);*
    
  •   	AtlasManager = Add(AtlasManager);*
    
  •   	InventoryManager = Add(InventoryManager);*
    
  •   	GameController = Add(GameController);*
    
  •   	// when you insert something new, don't forget to Add it*
    
  •   }*
    
  •   private static GameObject SafeFindWithTag(string tag)*
    
  •   {*
    
  •   	var GO = GameObject.FindWithTag(tag);*
    
  •   	if (GO == null)*
    
  •   		ThrowError("[Container]: GameObject of tag `"*
    
  •   			+ tag*
    
  •   			+ "` was not found!");*
    
  •   	return GO;*
    
  •   }*
    
  •   private static void ThrowError(string msg)*
    
  •   {*
    
  •   	Debug.LogError(msg);*
    
  •   	Debug.Break();*
    
  •   }*
    
  •   private static T SafeGetComponent<T>(GameObject from) where T : Component*
    
  •   {*
    
  •   	T comp = from.GetComponent<T>();*
    
  •   	if (comp == null)*
    
  •   		ThrowError("[Container]: Component `"*
    
  •   			+ typeof(T)*
    
  •   			+ "` was not found in the GameObject `"*
    
  •   			+ from.name);*
    
  •   	return comp;*
    
  •   }*
    
  •   private static T SafeGetComponent<T>() where T : Component*
    
  •   {*
    
  •   	return SafeGetComponent<T>(HoldAll);*
    
  •   }*
    
  •   public static T Add<T>(T member) where T: Component*
    
  •   {*
    
  •   	Object.DontDestroyOnLoad(member);*
    
  •   	return SafeGetComponent<T>();*
    
  •   }*
    
  •   public static void Ping(GameObject go)*
    
  •   {*
    
  •   	Debug.Log("[Container]: Hear you loud and clear, `" + go.name + "`");*
    
  •   }*
    
  •   public static void Ping()*
    
  •   {*
    
  •   	Debug.Log("[Container]: Everything's working fine. IT'S ALIVE!");*
    
  •   }*
    
  • }*
    As you can see it’s all clean, you got generics going on, minimal code and ease of usage.
    USAGE:
    1. Let’s say you wanted to add an
    AudioManager to your game, you
    first create the AudioManager
    class, attach it to a gameObject.
    2. Once you do that, you now come to the Container, and add a static property like you see above for your AudioManager - and add it to the system using AudioManager = Add(AudioManager); Which will add it to HoldAll (I will explain about it in a sec)
    3. Now you can enjoy Container.GameController.DoStuff(); (you can do the same static trick I did in the singleton to reduce keystrokes)
    One thing I haven’t mentioned, is the HoldAll idea. What you do is, to have a gameObject called HoldAll whose soul purpose is to hold persistence data (like managers, controllers and whatnot ) across scenes.
    You would create this gameObject in a scene, on its own! a Pre_Game scene, from that point you have your data with you, and you can travel between your scenes with your data carried with you. But just make sure that the user don’t have the ability to later come back to this scene, cause a lot of users had problems with that in that they had duplicates of the HoldAll object, so they go around it creating counter-measures (Mr Fattie’s new favorite word) by attaching scripts, that checks if they’re more than one object, the other gets destroyed, etc. I personally don’t find a reason for that, I just don’t go back to that scene and that’s it.
    A good idea, would be to have a simple script attached to your HoldAll gameObject, that simply does this:
  • void Start()*
  • {*
  •   Container.Ping(); // must bring it alive before loading anything game-related*
    
  •   Application.LoadLevel(1);*
    
  • }*
    And that’s it really, you start with your PRE_GAME scene, you Ping the Container just to bring it alive thus calling DontDestroyOnLoad. (Recall that, Container has a static constructor, and that gets only called when you access anything in the Container, that’s why Ping is enough for us)
    Of course, this HoldAll idea isn’t restricted to the Container system, in fact you should always use it (or something similar) to preserve/ keep your persistent data alive.
    This Container system works really great, I haven’t found any issues with it. [Yeah Mr.Fattie, yeah Grid!][9]
    I can’t really compare it with the Singleton implementation I gave you because I don’t have enough experience with either of those.
    Oh and, almost forgot, the Tags mentioned above (in Tags.holdAll) is just a class I always use to manage my tags:
    public static class Tags
    {
    public const string holdAll = “HoldAll”;
    // … add new tags as you move along
    }
    The const keyword makes the variable kinda static, and constant at the same time (you can’t change it) - So you could access the tags like Tags.Player, etc.
    ----------
    The final alternative I know about, is Mr.Jamora’s Monostate idea, found [here][10]. (@Jamora)
    I haven’t got the time to test it unfortunately, but I could tell you a couple of differences between it and the singleton. But first take a look at [this][11], to see how it’s implemented at its core (nice article btw). Now for the differences:
    - SINGLETON:
    - Only one instance! (Max one
    object)
    - Creational pattern.
    - Needs to be threadsafe!
    - Tough to inherit something.
    - Lazy initialization.
    - MONOSTATE:
    - Only one state! (You could have
    more than one object, but all have
    the same state)
    - Behavioral pattern.
    - Constructor is already thread-safe.
    - Could easily inherit.
    - Need to new up an object.
    ([Source][12])
    I hope that was helpful to you, and to others investigating the matter in the future.
    -V “Whether you think you can do it or not, you’re right in both cases ;)”
    ----------
    EDIT:
    Just came across a very nice well-written [book][13] about design patterns in games. [Here’s][14] the singleton part (Amazing stuff). I really liked every part in that book.
    ----------
    EDIT:
    Came up with a new system, “Verfices” - [Check it out][15] :smiley:
    [1]: Annihilator - Time Bomb - YouTube
    [2]: What are drawbacks or disadvantages of singleton pattern? - Stack Overflow
    [3]: design patterns - Are Singletons really that bad? - Stack Overflow
    [4]: http://suggestashow.com/blog/wp-content/uploads/2012/10/2-gus-fringe.jpg
    [5]: http://wiki.unity3d.com/index.php?title=Singleton
    [6]: language agnostic - Singletons: good design or a crutch? - Stack Overflow
    [7]: - YouTube
    [8]: How can I instantiate a prefab from a static function? - Unity Answers
    [9]: YEAH SCIENCE - YouTube
    [10]: Level Independant Data - Unity Answers
    [11]: The Monostate pattern - Simple Thread
    [12]: Redirect Notice
    [13]: Game Programming Patterns
    [14]: Singleton · Design Patterns Revisited · Game Programming Patterns
    [15]: http://forum.unity3d.com/threads/210080-quot-Verfices-quot-a-well-written-clean-documented-and-optimized-global-access-system!

I should think that the following would be sufficient:

public class GameController : MonoBehaviour {   
    public static GameController Instance { get; private set; }
 
    void Awake() {
        Instance = this;
    }

If you want to manage player controllers then something like the following might be useful:

public class PlayerManager : MonoBehaviour {
    public static PlayerManager Instance { get; private set; }

    // Players should add/remove themselves
    public List<PlayerController> players = new List<PlayerContorller>();

    void Awake() {
        Instance = this;
    }
}

public class PlayerController : MonoBehaviour {
    void OnEnable() {
        PlayerManager.Instance.players.Add(this);
    }
    void OnDisable() {
        PlayerManager.Instance.players.Remove(this);
    }
}

If there is need for just one version of the object across the entire lifespan of the application, then it makes sense to make the object a singleton. The nice part about a singleton is that its implementation hides away the troublesome concerns about whether an object has been created or not, so you never have to worry whether it is accessible or null at the moment you access it. Singleton implementations, when done right, are always globally accessible.

What worries me about your implementation is that your Singleton class does not have control over object instantiation itself. The value of the private singleton _instance is instead based on objects which are operable by the Unity API. So the class has no guarantee that its _instance might not become null outside its control at a later stage, if Unity decides to Destroy the object to which GameController is the attached script, for example. This could occur if a Scene change takes place and the object to which _instance refers isn’t marked with DontDestroyOnLoad. Additionally, this Singleton implementation cannot guarantee that GameController is actually globally singleton. As far as this code is concerned, there might be more GameObjects which have a GameController attached, and _instance just becomes the first one encountered by GameObject.FindObjectOfType. These issues work to defeat the purpose of singleton. If you want true singletons, your singleton class must have full control itself over object instantiation and destruction.