Day 101 — C# Fundamentals: Static Types
Hey and welcome!
Before moving onto the next project I wanted to quickly talk about Static Types and it’s advantages and disadvantages in Unity. This is something that I was looking into during the previous project but didn’t see a good chance to talk about it until I was done with that project. We did also have some brief exposure to static types when we looked into the Singleton design pattern back in the cinematography project but the more I looked into this the more I wanted to dedicate an article to it.
The general description of static information is that it’s something that will get stored inside the memory of the program for as long as the program is running.
Let’s see a practical example though.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Lives : MonoBehaviour
{
public int lives = 3;
}
In here I’ve got a regular old script that holds a variable with the number of lives in the game. It’s also public so it can be changed in the inspector and called from a separate script. I want to remove the value of 1 from lives every time that I press the space key, the code for that would normally look like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RemoveLives : MonoBehaviour
{
private Lives _lives; private void Start()
{
_lives = GameObject.Find("Lives_Holder").GetComponent<Lives>();
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
_lives.lives -= 1;
Debug.Log("You have " + _lives.lives + " lives left"); }
}
}
This is pretty standard stuff here where we look for the game object that holds the Lives script and then store that component to a variable in our Start() method so that it’s cached for later use when we remove the value of 1 from the lives property.
Now let’s see how things would look if we made the lives property in the Lives script static instead.
public class Lives : MonoBehaviour
{
public static int lives = 3;
}
In the Lives script all we need to do is add in the keyword “static” before the data type. Doing this will store lives in memory and also prevent you from changing it in the inspector in Unity.
public class RemoveLives: MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Lives.lives-= 1;
Debug.Log("You have " + Lives.lives + " lives left");
}
}
}
That’s gone and cleaned up quite a bit of code there! Since our lives property is being stored in the memory we can call to it directly with Lives.lives where Lives is the class name.
Now this is all fine and good but if you’re trying to build a large application and try to make everything you can static you’ll run across issues where there’s not enough memory left to actually run your application so it’s best to know when and where to make something static.
To know that we need to first know that the best perk of static information is the fact that it can be shared across multiple instances of a new object that you create with your class that holds the static type.
Better to see that in action though:
public class Weapon
{
public string name;
public float attackBonus;
public int id; public static int weaponCount; public Weapon()
{
weaponCount++;
}
}public class WeaponOverview : MonoBehaviour
{
private void Start()
{
Weapon spear = new Weapon();
Weapon sword = new Weapon();
Weapon club = new Weapon(); Debug.Log(Weapon.weaponCount);
}
}
This bit of code also doubles as a good way to show the difference between instance members and static members. In short the name, attackBonus and id variables can be considered as instance variables that can be copied and given values after we create our objects by accessing them with spear.name or sword.id etc.
This means that a spear and a sword can have their own unique values assigned to their respective instances of the variables. What makes our static member weaponCount interesting though is that it’s shared across all instances of objects defined by Weapon. Our spear, sword and club all have their weaponCount value set as 3, if we removed one of the objects it would be 2 and the 4 if we added an extra etc.
This means that the best time to make use of a static class is when you have data that will be shared across the entirety of your game and there’s only one of them. As an example, maybe you have a lobby that’s waiting for 12 players to join, using a static type for the playerCount you can let Unity know when that reaches 12. Or maybe you’re creating descriptions for Items in your game and you have individual classes for these to notify that it’s a Weapon type or a Food type you could define this tag as a static type so that every new instance of Weapon or Food will have a tag of “Weapon” and “Food” respectively.
This is some pretty fun stuff to learn about and I can already think of ways I could improve on some old code using these static types so I look forward to what I can do with these in the future!