A note on slimy static Unity3d gameObject instances

A quick note on the state of C# static variable instances in Unity3d.

So I just discovered that static properties of classes extending MonoBehaviour on level reload may get reloaded or not, depending on circumstances.

The problem is this: you may need in your game development to have a singleton manager class instance which is also a game object. Not me, of course, I am totally alien to such horrible hacks Con la lingua fuori, but you with your bad habits would like to have this which allows to hack the manager instance in the IDE and to have all the comfortable callbacks and methods of MonoBehaviour classes at your fingertips*. So what you do is as usual is have a static variable of the class type and set it to this on Awake.

Once you finished your first level, the question comes:  will my instance be reloaded at Application LoadLevel? It actually depends.

Documentation says that static variables are not reloaded with LoadLevel, that is, the virtual machine environment where classloader and code runs remains the same; but you will soon or later find that your instance instead does indeed get reloaded.

This simply because the instance is actually a game object, which gets destroyed, be it singleton or not. So if you have other static instances in your classes, not instances of game objects, those will be preserved. Your manager, won’t.

Actually once you are aware of this, it may come handy so to have static variables too being reloaded on level reload.

This is the correct code that ensures static persistence across levels also of game object instances, from here:

  1. public class myClass : MonoBehaviour {
  2. public static myClass i;
  3. void Awake () {
  4.   if(i==null) {
  5.     i = this;
  6.     DontDestroyOnLoad(gameObject);
  7.   }else
  8.     Destroy(gameObject);
  9.   }…

Hope this is clear.

 

Follow me on Twitter where I post about game design, game development, Unity3d 2D, HTML5, serious games.

* This is ugly from a OOP perspective because you (we) are instantiating a singleton manager, so a very slim object, by extending a very concrete class full of alien behaviour. But we’ll survive happily.

Social Share Toolbar

Comments

  1. Triffid Hunter says:

    I prefer the accessor singleton pattern, thus:

    /*
    * Accessor Singleton Pattern
    */
    private static GameManagerScript _instance;
    public static GameManagerScript instance
    {
    get
    {
    // find existing instance
    if (!_instance)
    _instance = GameObject.FindObjectOfType();

    // invoke prefab containing instance
    // if (!_instance) {
    // try
    // {
    // GameObject container = Instantiate(Resources.Load (“GameManager”), Vector3.zero, Quaternion.identity) as GameObject;
    //
    // _instance = container.GetComponent();
    //
    // // ensure instance permanence
    // DontDestroyOnLoad(container);
    // }
    // catch {}
    // }

    // create new GameObject to hold instance
    if (!_instance) {
    try
    {
    GameObject container = new GameObject();

    container.name = “GameManager Holder”;

    _instance = container.AddComponent();

    // ensure instance permanence
    DontDestroyOnLoad(container);
    }
    catch {}
    }

    // give up, everything is broken
    if (!_instance)
    throw new MissingComponentException(“Unable to find or create a GameManagerScript singleton!”);

    // give found or created instance to caller
    return _instance;
    }
    }

    void Awake() {
    if (!_instance)
    _instance = this;
    else if (_instance != this)
    {
    Destroy (gameObject);
    return;
    }

    // other initializations
    }

    This allows me to call GameManagerScript.instance wherever I like, whenever I like. I can even attach it to a GameObject in a scene if I like, or not.

    Note that all scripts that use the singleton should ideally cache the reference so we don’t have to run the instance getter every time

    • Cool, I like and use the accessor too; I would use Instance with a capital “I” for the public property.

Leave a Reply to Triffid Hunter Cancel reply

*