Making a script static - good practise?

Hi to all!

Browsing @Eric5h5 's Vectrosity’s code a while back, I noticed the following:

static var using : TheScript;

function Awake()
{
   using = this;
}

I’ve been using that trick more and more, so much so that if I know a script will only have one instance, I’ll automaticaly make it static. Avoids a lot of code maintenance, and is plain handy, but does it impact performance? Is it bad practise?

I use it a lot to reference stuff too, like this:

//MasterScript
static var using : MasterScript;
var slaves : Slave[]; //populate in inspector or in Awake(GetComponentInChildren)

function Awake()
{
   using = this;
}

Any script can then call MasterScript.using.slaves[slaveNb].DoWhatever();

I’d very much appreciate informed insights!

Cheers,

Gregzo

Static variables are bad practice. Use them sparingly. Not because they are really bad for performance (the GC collection does work differently though), but because most users misuse them.

My advice: only use one static variable for your singleton object, then put all other global variables in this singleton.


Example of typical misuse: referencing an object that is not persistent. Part of the object will be destroy automatically by Unity (i.e. Unity will forget about it) when loading a new scene. But most memory will not be release due to this last reference (and secondary references and cross-references), hence a memory leak.

Possible workaround: wrapper method for loading a level that takes care of releasing references + reconstruction of the references upon level loading.

And to prevent headaches asking myself whether this script or this other script should or not release references, I tend to generalize releasing references in all my script:

public class MyClass : MonoBehaviour
{
    MyOtherClass someRefObject = null;

    void Start()
    {
        // Get a reference to the MyOtherClass object, for example with FindObjectOfType
        this.someRefObject = (MyOtherClass) FindObjectOfType(typeof(MyOtherClass));
        
    }

    void OnDestroy()
    {
        // Release reference upon destruction
        this.someRefObject = null;
    }
}

Yes, I think this can be quite good… but every technique is only good to solve certain types of problems. Do you want a kind of manager class for something you know there will only be one of? For example, a SoundManager? In that case this can be much faster than finding an object with the component in the hierarchy or more memory efficient then storing a reference to the found object where it is used.

To extend the idea further, you may want to warn if using != null before it’s assigned… to make sure that the pattern is used properly. You may also need to be aware if objects are destroyed in Slave.