When should I use static fields/methods?

Hello everyone,
I’ve just started learning Unity and at the moment I’m simply following the tutorials available on the site. It’s all quite clear to me so far, but I’d like to ask you this one question which bothers me.

Assume this:
We’ve got a ‘GameController’ game object with a ‘Controls’ scripts attached to it as a component. The script holds a ‘score’ value that is to be displayed on the screen.
The ‘score’, however, must be updated inside another script, where the ‘point-addition’ condition is defined.

The issue is discussed in the Space Shooter Tutorial 3/02 ‘Counting points and displaying the score’. The eventual solution that is suggested to the viewer is to (operating on the second script) find the tagged ‘GameController’ game object (using FindWithTag), then create an intance of the ‘Controls’ class and finally use the previously written ‘AddPoints’ method to update the private ‘score’ value.

What I initially thought about when the problem was first stated was simply making ‘score’ and ‘AddPoints’ static, making operations between the scripts much simpler. It just seemed more natural to me - I think I don’t really need several GameController instances, but perhaps in the long run that indeed is a bad practice… How do you think? Are such ‘static operations’ something I should avoid if possible and the solution shown in the video was for a reason or is it just another valid approach?

Thanks for your feedback in advance!

Hi @jfilmie glad you are enjoying learning Unity so far.
It is kind of down to personal preference in my experience. Personally I tend to stay away from static fields whenever possible, however static functions are more acceptable.

Your first problem is that a static field cannot be viewed in the inspector, although this is a minor inconvenience. The second larger problem occurs most often when you are transitioning between scenes. Say you had a static field that tracked your score object. If you switched scenes the score object in the static variable would need to be manually reassigned in order to contain the correct reference. However a static method which executes GameObject.Find(“score”) would work identically across all scenes.

However GameObject.Find can be expensive when used in excess. A more elegant solution would be having an object that tracks the score that is flagged for Object.DontDestroyOnLoad. This can also be utilized through Singletons, but again you should be careful how often you utilize them.

Thanks for help!
I guess I’ll try to avoid using statics for now. Haven’t thought of possible problems with scene management, that’s truly worth noting. Thank you for pointing it out.

Short answer:

If you have to ask the question, you should probably avoid using them.

Long Answer:

You use static fields when you want something to be global. Another way of saying that is “almost never”. As @NashDevsoft mentioned, you can use static fields to support the Singleton pattern but it is important to be judicious about that.

The big risk is coupling. If you have a singleton that is write-only (like something that dumps analytics into the cloud) or one that is read-only (like something that tells you about the current device), you’re probably okay. Purely functional singletons are fine, too.

However, a lot of people fall into the trap of making read/write singletons. These are nothing more than glorified global variables because anything can couple to anything else indirectly by way of the singleton. Once you have something like that, you run the risk that any change anywhere in your system can impact any other thing in your system.

Once you are in that position, you’re always behind the eight ball. Testing becomes over-burdensome and your code is at constant risk of decay.