When to use static?

So so many people seem to be of the opinion that you never ever use anything static ever ever ever.

Then, sometimes, I see static methods being used within Unity tutorials.

I understand that classes that derive from Monobehaviour never have to be static:

public class MyClass : Monobehaviour {
  int myInt;
}

public class MySecondClass : Monobehaviour {
  MyClass myClass;
 
  Start() {
    myClass = this.gameObject.AddComponent<MyClass>();
    myClass.myInt = 10;
  }
}

…but when dealing with editor methods or methods in classes that don’t inherit from Monobehaviour, I have a tendency to want to create static methods so that I can access these utility methods:

public class xmlMethods  {
   public static void save(string filePath, Type objectType) {
      //save xml code goes here
   }
   public static void load(string filePath, Type objectType) {
      //load xml code goes here
   }
}

There’s a tendency to want to do this, creating utility classes that I can use anywhere in my scripts, but it confuses me when people say to never ever use static methods ever. What’s the alternative?

If anyone is saying to never use static ever, that’s ridiculous.

A static function makes perfect sense if, for example, it doesn’t rely on the state of any particular object. Good examples are math-ish functions (think Vector3.Lerp, or Mathf.Sin) which are simple in → out functions where all the information they use comes directly from the parameters being sent.

It makes sense to be static if it has to do with the state of the system itself, which is why many filesystem-accessing functions are static.

If you’re using a singleton pattern or something similar, that obviously involves using static. Using singletons in itself comes with its own data-design caveats and should not be used carelessly, but if you’re using one, the use of static is required (otherwise what’s the point?)

3 Likes

I literally was coming into this thread just now to ironically post “never”.

1 Like

Do they offer any explanation? Either they don’t know what static is, or their opinion is taken out of context.

static methods should be stateless

if you require state, then you’re probably using static incorrectly

(of course some patterns skirt this… like singleton)

What I mean by ‘stateless’ vs ‘stateful’ is that a stateless method acts the same way regardless of the state of the program. Where as a stateful method can act differently just because.

For example the UnityEngine.Mathf and System.Math classes are full of static method. If I call Math.Sin(x), it’ll act like Sin, regardless.

Where as if you call ‘GetComponent’ on a GameObject (not a static), it depends on the state of said GameObject you’re calling it on that determines the result you will get.

Do note though… you could have a static version of this. Often written as extension methods… this is often fine as well.

But if lets say you had a ‘global/static’ ‘GetComponent’ that returned a component off some arbitrary gameObject in the scene. Yeah… that’s probaby a bad design (again, singleton sort of skirts this… but, singleton also has huge criticisms because of this).

Where we start REALLY get into issues though is that some people use statics for some really bad things.

Lets say for instance that you have a PlayerAttack script and a EnemyHealth script. PlayerAttack wants to reduce the health of EnemyHealth when some event occurs (button press, trigger enter, something). Thing is PlayerAttack doesn’t have a reference to EnemyHealth… so some people will put a ‘static’ variable on EnemyHealth called ‘Health’ and then PlayerAttack just says:

EnemyHealth.Health -= 1f;

Well… yes, this does reduce the health of EnemyHealth. BUT now all EnemyHealth’s share the same health. You can’t have 2 enemies now… or rather if you have 2 enemies, and you kill one… the other dies as well.

And it’s these sorts of designs that people are talking about when they say “never use statics”. Because rather than wanting to explain the complicated relationships of objects in a game… it’s easier to just say “don’t do it!”.

It’s like a religious parent telling their kids abstinence only, and never once explaining the birds and the bees.

9 Likes

@lordofduct gave some pretty good ideas. I think some are just confused on how static works or want to keep new coders from overusing it or using it incorrectly. Just take the time to understand them and there is no reason not to use them when appropriate.

The thing I usually see people ranting about is when someone answers the question “How do I access a variable on one script from another script” with “Put the word static in front of everything” which is absolutely a terrible answer and generally means no one involved knows what static means. Those people should all be garbage collected. :stuck_out_tongue:

The other thing I’ve seen is people saying you should avoid Singletons, which I do agree with. Overuse of singletons can make your code into a mess of dependencies, where you can’t unit test your “Jump” function because that calls your SoundManager singleton and your ParticleManager singleton and your NetworkManager singleton which in turn call your FileManager singleton and your GameStateManager singleton which requires all your other singletons etc, etc. It makes it impossible to separate anything and requires that you have fifty managers all set up correctly when all you want to do is see if you’re calculating the jumping force correctly. People who overuse Singletons don’t need to be garbage collected, though. They usually just need to wait until their project becomes gigantic and they want to unit test before they decide to manage dependencies a little more carefully.

I’ve never seen anyone say you should never use static ever though. That seems dumb.

3 Likes

I only use static in 2 places: for consts and for manager/singleton entry points, when building systems for a game.

1 Like

You can only use static once you can explain why you should never use static.

There are plenty of legit use cases for static, as explained above. But you should avoid all of them until you can understand and explain the ‘never-ever’ argument.

Once you understand the risks, you are free to go.

2 Likes

I see this is an old thread, but would it make sense to put static on a Player’s health then, since it only will affect the player, to keep its health between scenes instead of DontDestroyOnLoad()?

Like… static int numberOfHearts = 3;
static int health = 3;

Until you need more than one player object with different health for any reason. Local multiplayer is just one, but testing for example. Or special cutscenes or any special state which requires you to duplicate your player object. The static exist only once and it’s the same for every player object.

1 Like