0
\$\begingroup\$

I have a game where my code is designed to be on a single scene so I've implemented a singleton like that:

public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static bool _applicationIsQuitting;
private static readonly object Locker = new object ();
protected static T Instance;

public static T GetInstance {
    get {
        if (_applicationIsQuitting) {
            return null;
        }

        lock (Locker) {
            if (Instance == null) {
                Instance = (T)FindObjectOfType (typeof(T));

                if (FindObjectsOfType (typeof(T)).Length > 1) {
                    Debug.LogWarning ("More than one Singleton of type : " + typeof(T));
                    return Instance;
                }

                if (Instance == null) {
                    var singleton = new GameObject ();
                    Instance = singleton.AddComponent<T> ();
                    singleton.name = "(MonoSingleton) " + typeof(T);

                    DontDestroyOnLoad (singleton);

                    Debug.Log ("An instance of : " + typeof(T) + " is needed in the scene, so " + singleton +
                    " was create with DontDestroyOnLoad");

                    return Instance;
                }
                Debug.Log ("Using instance already created : " + Instance.gameObject.name);
                return Instance;
            }
            return Instance;
        }
    }
}

public void OnDestroy ()
{
    _applicationIsQuitting = true;
}

#region virtual methods


public virtual void Awake ()
{
        Debug.Log ("Awake".ColorMe (Color.green) + " instance of : " + typeof(T));
}
#endregion
}

But now with my game growing, I want to split it into mulitple scenes (easier to do now with Unity 5.3).

I mainly use singleton to manage UI. And for this i've a UI GameObject containing my script for current scenes. So on GameObject Awake it create a reference to my Scrit that i can call with script.GetInstance.

My problem is when i refresh a scene or i use a ui component that is already used in previous loaded scene my GetInstance return null. Is there any way to refresh instance reference in virtual Awake method ?

EDIT:

Obviously OnDestroy() set _applicationIsQuitting to true, so GetInstance return null. I've try to set it to false on Awake() but it doesn't change anything so I do that :

public static T SetInstance {
    set {
        Debug.Log (Prefix + ("Updating instance of : " + typeof(T)).ColorMe (Color.yellow));
        _applicationIsQuitting = false;
        Instance = value;
    }
}

and on each class when I awake i do the following :

public override void Awake ()
{
    base.Awake ();
    myScript.SetInstance = this;
}

I prefer to have separated getter and setter to provide myself mode readability.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Problem is that _applicationIsQuitting is a static variable. You, probably, should set it in false on Awake call.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks, you helped me a lot. And allow me to save a large amout of time ^^ \$\endgroup\$
    – Sata
    Jan 3, 2016 at 16:52
  • \$\begingroup\$ Nice to hear it. But be careful with Singletons, they are really dangerous and can make you a lot of problems there and bring painfull headeach. \$\endgroup\$ Jan 3, 2016 at 17:00
  • \$\begingroup\$ After some reflection i try to remove this for UI management but so far, i have more than 300 scripts just for UI... \$\endgroup\$
    – Sata
    Jan 3, 2016 at 17:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .