Singleton does not work as expected

I have 2 classes UIController and GameController inherit a generic Singleton class.

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    static T ins;
    public static T Ins { get { return ins; } private set { ins = value; } }
    void Awake()
    {
        if (ins != null && ins != this)
        {
            Destroy(gameObject);
        }
        else
        {
            ins = this as T;
            DontDestroyOnLoad(gameObject);
        }
    }
}

But when I start the game, only GameController is created in the Don’tDestroyOnLoad field and the UIController is not. Where did I do wrong?

Here you go:

    public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
    {
        private static T instance = null;
        private static readonly Object syncRoot = new Object();

        public static T Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = FindObjectOfType(typeof(T)) as T;
                            if (instance == null)
                                Debug.LogError(
                                    "SingletoneBase<T>: Could not found GameObject of type " + typeof(T).Name);
                        }
                    }
                }

                return instance;
            }
        }
    }
2 Likes

Good stuff @Terraya … and here’s my personal favorite. :slight_smile:

ULTRA-simple static solution to a GameManager:

https://discussions.unity.com/t/855136/6

https://gist.github.com/kurtdekker/50faa0d78cd978375b2fe465d55b282b

OR for a more-complex “lives as a MonoBehaviour” solution…

Simple Singleton (UnitySingleton):

Some super-simple Singleton examples to take and modify:

Simple Unity3D Singleton (no predefined data):

Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

public void DestroyThyself()
{
   Destroy(gameObject);
   Instance = null;    // because destroy doesn't happen until end of frame
}

There are also lots of Youtube tutorials on the concepts involved in making a suitable GameManager, which obviously depends a lot on what your game might need.

And if you really insist on barebones C# singleton, here’s a Highlander:

Also, for OP, if you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: https://discussions.unity.com/t/481379

You may edit your post above.

2 Likes

Thank you so much. Both answers are great answers for me.

1 Like