Unity Singleton and static variables for Beginners

Unity Singleton or Singleton in general is a globally accessible class with all its objects referring to a single instance at any given time. Now a Singleton can have multiple objects but any reference to the class at a given point from different scripts will be to one single instance.

Confusing?

You won’t be confused after reading the next paragraph.

When an object of a class is created, a memory is allocated to store its properties. In case of a Singleton, no matter how many objects are created they all point to the same memory location or otherwise termed as instance.

Unity singleton block diagram
Unity Singleton block diagram

So, to avoid confusion we only create one object of a Singleton class and check if any duplicates exist and destroy them. we will see how in the later section of this tutorial.

In this tutorial, we will see how to create a singleton class using the static property and also how to implement their usage in the correct way.

How to create a Singleton in Unity?

You can make a class as a Singleton by declaring a public static object of the class. With this object you can access any variable or method inside the class using the class name without needing to reference it first.

Let’s see some example

Unity sale

public class example : MonoBehaviour 
{
    public static example my_object;

    float my_player_health=100;
}

In the above code the example class is a singleton and has a static object called my_object. Now if I want to access the variable my_player_health from other scripts I can do it like this

public class test: MonoBehaviour
{
   
   void Start()
   {
      float player_health=example.my_object.my_player_health;
   }

}

You can read and write the properties of any Singleton class. But if you want to change the read and write properties of a Unity Singleton class you can do that when declaring the static object.

Here is an example of how you can make the Singleton Read-only.

public class example : MonoBehaviour 
{
    public static example my_object { get; private set; } ;

    float my_player_health=100;
}

How to Find and delete the duplicate instances of a Unity Singleton?

As we discussed in the introduction a singleton class can have more than one object but all of them refer to the same instance. This adds to more confusing and makes it difficult to implement a singleton.

To avoid this confusing, we can just add a code to check if the instance created is the only active instance of the class. If not, the instance can self-destroy itself.

In general C# code you can use a constructor of the class to do this but Unity does allow constructor so we can add the code to the Awake function.

public class example : MonoBehaviour 
{
    public static example my_object { get; private set; } ;

    float my_player_health=100;

     private void Awake()
    {
        if (my_object != null && my_object != this)
        {
            Destroy(this);
        } else {
            my_object = this;
        }
    }
}

Where to use Singletons in Unity?

To avoid Multiple instances of the same class

Singletons are generally used for data that might be required to different scripts. For example, the player data. Player data is accessed by multiple scripts for different purposes.

The UI accesses the data to display health bar, the scene manager requires it to load scenes, the audio manager requires it to play audio and so on.

All these scripts can create an instance for the player class and access the data but that will be a waste of resource. Instead of that you can create a single Singleton class for the player which holds all data like Player health, position, ammo etc.

All the other scripts can use the player data without creating an instance for the class.

To improve performance

My coders in Unity have a habit to use “GameObject.Find” very extensively. This is very performance hungry and you can avoid them using a Singleton if you need the same Gameobject in different places.

For example, if you need to change the color of a Gameobject based on the score then you need to find the gameobject with the score to read the value.

If you had made the score class into a Singleton, you can access it just by using the name and there is no need to find the Gameobject.

Here is the example code

public class example : MonoBehaviour 
{
    public static example my_object;

    float my_score;
}
//In a different script
public class test: MonoBehaviour
{
   
   void Start()
   {
      if(example.my_object.my_score>50)
     {
        myobject.material.color=color.red;
      }
   }

}

If the write access is enabled then you can set the value of score from any other script you want.

like this

void update_score()
   {
      if(hit)
     {
        example.my_object.my_score-=10;
      }
   }

How to Avoid the Singleton from getting destroyed on Scene load?

Even though a Singleton is very handy, it’s important to note that it gets destroyed on scene load. So, if you set your player health in the intro scene and switch to the game scene, then all the data is gone.

Unity provides a way to avoid this by not destroying the Singleton when the scene changes.

You need to add just a single line to code for this. It’s called “DontdestroyOnLoad“.

public class example : MonoBehaviour 
{
    public static example my_object { get; private set; } ;

    float my_player_health=100;

     private void Awake()
    {
        if (my_object != null && my_object != this)
        {
            Destroy(this);
        } else {
            my_object = this;
        }
       DontDestroyOnLoad(this.gameObject);
    }
}

Static variable and methods in Unity

Singleton are actually static instances of a class. Similar to a class you can also create a static variable and a static method. A static variable or method can be accessed from anywhere or any other script using the class name.

You don’t need the object reference to access the static properties.

To declare a static variable or method you need to use the keyword static similar to how we declared the static object of a class.

Here are the examples

Static Variable

public static int level_count;

Static Method

public static void my_method()
{

}

Let’s say they are a part of the class example. Now to access the data you can simply use the class name with needing to reference it.

int my_value=example.level_count
example.my_method()

Singleton vs Static variable usage in Unity

Both are very similar when it comes to how the data is stored. Depending on your requirement, you can decide if you have to use a Singleton class or a static variable.

Let’s consider an example for better understanding.

If you need only the player health variable in all scripts then there is no point in making a Singleton player class you can only have a static player health variable.

If you need all the methods and variables inside the player class then it’s better to create a singleton rather than creating multiple static properties.

Hope this clears everything about Singletons in Unity. If you have any questions feel free to leave them in the comment box below.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.