Create a persistent GameObject using Singleton

Hi all! :slight_smile:
I need to have a GameObject that doesn’t destroy when a new scene is loaded (or if the same scene is reloaded). So I went for the Singleton pattern, and took the Singleton.cs and MonoBehaviourExtended.cs files from the Unify Wiki

Then I created my singleton class:

using UnityEngine;

public class ControllerBehaviour : Singleton<ControllerBehaviour> {

	protected ControllerBehaviour() {}

	public float foo = 0;
}

Then I created a GameObject called Controller and I added that script to it.
The problem is that it seems that the Controller GameObject destroys when the scene is reloaded using this instruction:

Application.LoadLevel(Application.loadedLevelName);

I say it because I have an object Ball that, when collides with another object (called Checkpoint), it increments the foo variable of the Controller object.

void OnTriggerEnter2D(Collider2D other)
{
	if (other.gameObject.name == "Checkpoint")
	{
		ControllerBehaviour.Instance.foo++;
		Debug.Log("ControllerBehaviour.Instance.foo = " + ControllerBehaviour.Instance.foo);
		}
	}

Initially it works fine, but after the scene is reloaded, when that collision happens, I get the following Warning and Error to Console:

WARNING: [Singleton] Instance ‘ControllerBehaviour’ already destroyed on application quit. Won’t create again - returning null.
UnityEngine.Debug:LogWarning(Object)
Singleton`1:get_Instance() (at Assets/scripts/Singleton.cs:21)
Ball:OnTriggerEnter2D(Collider2D) (at Assets/scripts/Ball.cs:69)

ERROR: NullReferenceException: Object reference not set to an instance of an object
Ball.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/scripts/Ball.cs:69)

Why does it happen? I used the Singleton class from the Unify Wiki, that contains the DontDestroyOnLoad() function.

Thank you in advance for your help! :slight_smile:

I have a bit of a hack that I use a lot:

public class myClass : MonoBehaviour {
	public static myClass i;
	
	void Awake () {
		if(!i) {
			i = this;
			DontDestroyOnLoad(gameObject);
		}else 
		        Destroy(gameObject);
	}...

Then if youw ant to use it, from anywhere in code, do myClass.i.whatever. Added bonus is that fields are still available in the inspector

EDIT:Added the else statement to make it appropriate regarding the title (singleton)

Just a word of warning regarding a Unity bug that cost me a few hours. I’m using the same unify wiki singleton script above, and started getting the “already destroyed on application quit. Won’t create again - returning null” error. It turned out that Unity had actually managed to save one of my dynamically created singleton objects into a scene file.

So in my hierarchy (while not in play mode) I had a game object that was clearly created by the script because it was named “(singleton) GameManager”. For some reason it remained in the scene file when I stopped playing. I deleted it and everything was fine again.

Hi All,
I know that this thread has been around for a while. I was having similar design conundrum and stumble about this thread. The answer by @joonturbo is 90% correct. But instead of using Destroy, you should use DestroyImmediate. The Unity documentation has big warnings with regards to using DestroyImmediate outside the context of an editor script (never set the second parameter to true or else the actually assets on your hard drive will be permanently deleted!). But without DestroyImmediate, this technique isn’t a true Singleton pattern. The reason is that, Destroy, happens after the first update. This means that you second object isn’t deleted until the whole scene has had a chance to run, and every other object has had it’s awake, start, update (and all other unity method) called at least once. This is becomes problematic if you have reference to your singleton object, by another singleton object (and you haven’t set the proper execution order, and even then you end up with a possible deadlock).
Bref, to make this gameobject truly unique and avoid another object getting a handle on an invalid version of the object due to DontDestroyOnLoad, or another object with the script attached in the scene, use DestroyImmediate instead of Destroy, so that the secondary instance, gets destroy right away.
The code ends up looking more like this:

public class PersistentGameObjectSingleton<T> : MonoBehaviour where T : MonoBehaviour
    {
        #region Public Accessors

        /// <summary>
        /// Static instance of PersistentGameObjectSingleton which allows it to be accessed by any other script.
        /// </summary>
        public static PersistentGameObjectSingleton<T> Instance { get; private set; }

        #endregion

        #region Unity methods

        /// <summary>
        /// Things to do as soon as the scene starts up
        /// </summary>
        void Awake()
        {
            Logging.Log("{0} - Awoken. Initializing Singleton pattern. Instance Id : {1}", this.GetType().Name, gameObject.GetInstanceID());

            if (Instance == null)
            {
                Logging.Log("{0} - Setting first instance. Instance Id : {1}", this.GetType().Name, gameObject.GetInstanceID());

                //if not, set instance to this
                Instance = this;

                //Sets this to not be destroyed when reloading scene
                DontDestroyOnLoad(gameObject);
            }
            else if (Instance != this)
            {
                Logging.LogWarning("{0} - Destroying secondary instance. Instance Id : {1}", this.GetType().Name, gameObject.GetInstanceID());

                //Then destroy this. This enforces our singleton pattern, meaning there can only ever be one instance of a GlobalManager.
                DestroyImmediate(gameObject);

                return;
            }
        }

Note: I generalized the pattern using templates, so that you can easily use it on any other class.
Hope this little tip helps any other person in the future who stumbles upon this thread.

Cheers,