top of page
Search
  • alexlpc2015

[Unity Coding Designs] #01 - Singleton

Hi and welcome to my Unity Coding Designs Series!

This is a comprehensive series about various coding designs in unity. Some of the scripts are included in my unity utility plugin SKCell. I hope you find this helpful!


Coding Designs #01 - Singleton


Singleton class is a commonly used design pattern in software development. Singletons are usually used on unique classes like managers and the main character.

One of the main purposes why we use singletons in games is that we can easily access the reference of the class.

For example, we have a mono behavior class and another class we want to get the reference to.

public sealed class TestScript : MonoBehaviour
{

}

public class Player
{

}

Since the Player class is not static, we can only get its reference by declaring an instance of Player and trying to get it using a function or assigning it in the unity inspector.

public sealed class TestScript : MonoBehaviour
{
    private Player player;

    private void GetPlayer()
    {
        //...
    }
}

This method can be very messy if many of our scripts are trying to get the player reference.

To solve this problem, we can make the Player class initialize a static instance of it during Start.

public class Player : MonoBehaviour
{
    public static Player instance;

    private void Start()
    {
        instance = this;
    }
}

We can now access the instance simply by Player.instance. Very convenient, right?

public void SetPlayerHealth(float delta)
{
    Player.instance.hp += delta;
}

Another important feature of a singleton is its uniqueness, meaning that there should always be only one instance in the scene. (e.g. if there are multiple managers in the scene, a huge amount of data will be messed up)To implement this feature, we can use the getter of the instance field to avoid duplicates.

public class Player
{
    public static Player instance { get { return instance ?? new Player(); } }
}

This works well, but it would be nice if we can write a base class for singletons and we can derive from that class to whenever we want a singleton.

It can be written this way:

public class Singleton<T> where T : class, new()
{
    protected Singleton() {}

    private static T _inst = null;

    public static T instance => _inst ?? (_inst = new T());

    public static void Clear()
    {
        _inst = null;
    }
}

To use it, simply derive from it and then access it by .instance.

public sealed class TestScript : MonoBehaviour
{
    public void SetPlayerHealth(float delta)
    {
        Player.instance.hp += delta;
    }
}

public class Player : Singleton <Player>
{

}

We can make a MonoBehaviour singleton using the same method:

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
    private static T _inst = null;

    public static T instance
    {
        get
        {
            return _inst;
        }
    }

    protected virtual void Awake()
    {
        _inst = (T)this;
    }
}

These are super useful in game development, remember to implement them on your own!



10 views0 comments
Post: Blog2_Post
bottom of page