Singletons in Unity

Singletons in Unity (done right)

In Advanced Scripting by John FrenchUpdated 34 Comments

This article is part of a series on Design Patterns in Unity.

Even if you’re new to Unity, you probably already know that Singletons can be a controversial topic.

You might have heard that they are useful, but also never to use them.

And that, if you do, your game will be difficult to manage as it gets bigger.

However…

While there are good arguments for not using singletons, for a beginner, who’s just trying to get their game finished, singletons can be a useful and simple way of connecting scripts.

And it’s not just beginners who find singletons useful, as there have been many Unity developers who have been happy to use singletons in their games as well.

So what’s the deal with singletons?

Are they helpful or harmful?

And is it ok to use one in your project?

Well, that depends…

Generally speaking, many of the problems that can occur from using a singleton are caused by how you choose to use them in your project, not by the singleton itself. 

Some singleton methods can be more problematic than others but exactly what issues you’re likely to run into depends on your specific project and what you have planned for it.

This is because, a lot of the time, the effect of using a singleton may only start to become clear later on, as your project grows bigger or when you try to change something.

Unfortunately, this means that the risks of using a singleton can be unclear, but don’t worry…

In this article, I’ll show you some of the different ways you can use singletons to make building your game easier, along with some of the potential risks involved, so that you can make the right decision about whether or not to use singletons in your game.

Here’s what you’ll find on this page:

Singletons in Unity: Overview video

For a general overview of how to use Singletons in Unity, try my video, or continue to the full article below.

So, what even is a singleton?

What is a singleton in Unity?

Generally speaking, a singleton in Unity is a globally accessible class that exists in the scene, but only once.

The idea is that any other script can access the singleton, allowing you to easily connect objects to important parts of the game, such as to the player or to other game systems.

Which can be useful for connecting unrelated objects and scripts to global systems, such as an audio manager, for example.

So how do they work?

A singleton in Unity is a normal class that can be added to an in-game object.

What’s different about a singleton, however, is that the class holds a public static reference to an instance of its own type.

Like this:

public class Singleton : MonoBehaviour 
{
    public static Singleton instance;
}

The static reference is what makes a singleton globally accessible.

Making a variable static means that it is shared by all instances of the class, meaning that any script can access the singleton through its class name, without needing a reference to it first.

Like this:

Singleton.instance;

This means that any public methods or variables that exist in the singleton class can be accessed by other scripts in the game easily.

However, because any script can access it, it’s generally a good idea to protect the instance variable with a property, which simply means that it can be read by other scripts, but it can only be set from within its own class.

Like this:

public class Singleton : MonoBehaviour 
{
    public static Singleton Instance { get; private set; }
}

While the reference to the script is static, meaning that it is the same in any and all instances of the class, the instance that it points to is not.

Meaning that, while the reference can only ever point to one instance of the script, it’s possible to have more than one instance of the singleton in the scene.

Which is why it’s important to make sure that there is only ever one instance of the singleton by checking to see if the static reference, if there is one, matches the script instance.

Then, if it doesn’t match, the script knows that it’s a duplicate and it can delete itself.

Like this:

public static Singleton Instance { get; private set; }

private void Awake() 
{ 
    // If there is an instance, and it's not me, delete myself.
    
    if (Instance != null && Instance != this) 
    { 
        Destroy(this); 
    } 
    else 
    { 
        Instance = this; 
    } 
}

These are the two basic requirements for a singleton.

A globally accessible class, but with only one instance.

But why would you make a singleton, and what can you do with them?

Why use a singleton?

Singletons can be very convenient because they allow you to connect parts of your game more easily.

For example, you could use a singleton to make the player’s position publicly accessible to enemies, or use one to expose the player’s health to the UI.

Like this:

float healthBarValue = Singleton.Instance.playerHealth;

Or, you could call a sound effect function on a singleton from any script in the game.

Like this:

Singleton.Instance.PlaySound(clipToPlay);

So long as the variable or function exists on the singleton, and it’s publicly accessible, other scripts will be able to use it without you needing to set up a reference to it first.

Which can make connecting the different parts of your game much easier.

However…

While singletons can be easy to use, they can also cause problems.

Using a singleton to solve a problem you have right now, might create a different problem later on, so it’s worth being aware of what could happen if you choose to use a singleton in your project.

So, what’s the worst that could happen?

What’s bad about singletons?

Generally speaking, singletons can make it difficult to manage your project as it gets bigger.

They can make your project harder to change, more difficult to extend and can cause problems with testing. 

If you’ve looked into using singletons at all, then you may have already heard some of these objections, but what do they actually mean for you?

What, specifically, could go wrong when using a singleton?

One of the biggest risks with singletons is, by design, the very thing that makes them convenient in the first place, global access.

For example, allowing every script access to a game manager singleton can be extremely useful.

So, how is that a problem?

I’ll explain…

Game manager singletons

One of the main benefits of using a singleton in your project is to avoid needing to tightly connect important scripts, such as game managers, with the many different objects that may need to access them.

Such as an audio manager, for example.

It would usually be bad design to try to connect every single object that wanted to play a sound to the audio manager script manually.

Likewise, it could be very bad for performance to try to find the audio manager in the scene every time a new object that might need it is created.

For that reason, an audio manager singleton can make a lot of sense.

So, let’s say that you do exactly that, that you create an Audio Manager singleton with a public Play Sound Effect function.

Like this:

public void PlaySound(AudioClip clip)
{
    audioSource.PlayOneShot(clip);
}

Now, whenever you want to play a sound, you can simply call the audio manager and pass in a sound effect.

Like this:

public AudioClip soundEffect;
void Start()
{
    Singleton.Instance.PlaySound(soundEffect);
}

Simple and convenient…

But is there anything wrong with this method?

Will using it cause you a problem?

For what it aims to do… no there’s nothing really bad about using a singleton in this way.

However…

The problem you’ll probably run into when using a singleton like this is if and when you decide you need to change how sound effects are triggered.

For example, you might start to use this method, adding a sound effect trigger anywhere you need to, calling the sound effect function from many different scripts.

Which, depending on the size of your game, could be tens or hundreds of different places, all calling the script in the exact same way.

Game Manager Singletons visualisation

Singletons can be used to give many different objects easy access to game systems, which can be both good and bad.

Then, as you start to add sounds to your game, you might notice that some are louder than others, while others are beginning to sound repetitive. 

So let’s say that you decide that you’d like to make a sound’s volume adjustable when you trigger it, so that different clips can be played at different levels and that you’d also like to add in some extra variations of some sounds when they’re triggered, to prevent them from becoming repetitive.

In isolation, these are simple features that are relatively easy to create.

Except that doing it now will probably be a difficult task, because every sound trigger in the game has a direct line to the audio manager and simply calls the function as it is, passing in an audio clip reference and nothing else.

Which means that, to change how the audio manager works now, you’d need to change every script that calls it too.

Which could be a lot of work.

Modular event triggers in Unity

When using singletons, it’s easy to lock in certain functionality early on, making things difficult to change later.

Events, however, by design, can be a useful way of changing the response to something that happens in a game, but without changing what triggers it.

For example, it’s possible to make a basic events system that would allow an object, any object, to trigger a sound effect event, but where the response to that event, such as what sound is played and how it’s handled, takes place on the audio manager and can be easily changed without needing to change what triggered it.

While this is also possible to do with singletons, events can be more forgiving when you want to change something later, since the trigger can be more easily removed from the response.

While having to change what a singleton does after you’ve made it isn’t easy, it’s not necessarily a major issue.

For example, while it would definitely be difficult to change the sound effect function at a later date, it wouldn’t be impossible.

However, knowing this, it can be helpful to treat every public function and variable that you expose to other objects using a singleton as if it’s something that can’t be changed.

Then, by building in the functionality you’re expecting to need early on, you can minimise the risk of needing to change how it works later.

An audio manager is, potentially, a good fit for a singleton because global access and an in-scene presence make using it easier.

Put simply, the main benefits of using a singleton match the problems of the task.

However…

Just because a singleton seems like a good solution to a problem, doesn’t always mean that it will be.

And, just like before, how you choose to use a singleton now, will affect what you can do with your game later.

Which can be especially true when using a player singleton.

Player object singletons

One common use for singletons is to expose certain characteristics of the player to other scripts in the game, such as the player’s position or their current health.

Which makes a lot of sense when you think about it.

After all, just about every object in the game is probably going to respond to the actions of the player in some way, so making it easy for them to access the player and their scripts seems like a good idea.

But, what problems could be caused by using a player object singleton?

Player singleton visualisation

A player object singleton can be used to give every object access to the player, but it’s not without its drawbacks.

Generally speaking, deciding when it’s ok to use a player object singleton can be a lot like deciding whether or not it’s ok to use a static variable.

Using a static variable, which is essentially a global variable, is generally fine, so long as you only intend to ever have one variable of that type in the game. 

Singletons have the same vulnerability.

Because scripts that need to reference a singleton do so directly, each script, essentially, has a tight connection with the player.

Meaning that adding a second player at a later time could be extremely difficult or impossible, depending on how tightly integrated the player singleton is with scripts that need to access it.

Generally speaking, using a singleton to manage a unique, individual object, such as a player, carries more risk than using one to manage a game system.

And while it may not be a problem for you and your project now, using a singleton in this way can cause significant issues further down the line if you’re not absolutely sure what your game is going to be like or what features you might like to add in the future.

Scriptable object variables vs singletons

Normally, a script’s variables are explicitly typed out, meaning that, if you want a health bar to check the health of the player, for example, you will often need to reference a specific instance of that player’s health script and variable.

While singletons make this easier to do, they don’t change the fact that you’re still directly referencing a specific script on a specific object in the scene. If you ever need to change it, you’ll have to rewrite the code, which is why singletons can make it hard to refactor code later.

Scriptable object variables, on the other hand, work in a different way. They can be used to reference a variable type instead of a specific variable.

Which means that, instead of referencing the player’s health, they can, instead, reference a player’s health. The health variable can be easily swapped out in the Inspector for a variable of the same type but on a different object. Meaning that you could, for example, create a whole second player, with their own health bar, and all you’d have to change is which health variable type the health bar was reading from.

Which is as simple as swapping out the scriptable object in the Inspector, without changing the script.

Using a singleton can sometimes make managing your project more difficult as the references you use will often be direct, explicit references to singleton objects, such as the player or some type of game system.

What’s more, if you’ve gone down the route of using singletons, you may have multiple singleton systems in your game.

Which can make it very difficult to keep track of which script is doing what, since any script can do anything.

However, it’s possible to limit some of the problems that can be caused by global system access, while still leveraging the benefits of using a singleton in the first place.

For example, with a master singleton, that provides access to other game systems through a single point of access.

Master singletons (service locators)

This approach, while it uses a singleton, is technically a different design pattern called the Service Locator, which uses a gateway singleton to manage access to multiple other game systems.

Which can be useful when you want the functionality and ease of access that a singleton can provide, but with an extra layer of control.

Master Singleton visualisation

A “service locator” style singleton can be used to provide access to other, non-singleton scripts.

This works by adding a single master singleton in between your game’s systems and the objects that might want to access them.

Like this:

public class Singleton : MonoBehaviour
{
    public static Singleton Instance { get; private set; }

    public AudioManager AudioManager { get; private set; }
    public UIManager UIManager { get; private set; }

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(this);
            return;
        }

        Instance = this;

        AudioManager = GetComponentInChildren<AudioManager>();
        UIManager = GetComponentInChildren<UIManager>();
    }
}

In this example, the audio manager and UI manager are child objects of the singleton.

Setting up a master singleton

When using this method, you’ll need to set up the singleton’s references using Get Component in Children, because read-only references can’t be set in the Inspector.

Also, because a destroyed component is deleted on the next update loop, the Get Component calls will still take place even if the script is going to be removed. 

Which is why it can be helpful to use the return keyword if the script is going to be destroyed, to stop the function progressing any further if it is a duplicate.

You will then be able to access the individual systems of your game via a single entry point, by referencing the singleton instance and its subsystem.

Like this:

Singleton.Instance.AudioManager.PlaySound();

While this doesn’t prevent the problems that can be caused by needing to change your code later, it does add a layer of abstraction between your singleton systems and the objects that might want to access them.

Which can make it easier to build your game in a way that is less challenging to extend.

For more information on Master Singletons and how to use them, try Thousand Ant’s video here.

What’s the right way to use a singleton in Unity?

While there’s no one right way to use a singleton, the problems that could be caused by using one usually depend on your project and what you plan to do with it.

This is because the risks of using a singleton are more to do with how you choose to use it and less about the singleton itself.

For example, using a player object singleton when you might want to add extra players later will probably cause you major issues.

While allowing global access to a file save system could cause problems if two scripts unknowingly try to save the game at the same time.

And building your singletons before you know what you want to do with them can make it much harder to update them later when something needs to change.

However…

There may be times when using a singleton makes a lot of sense.

Especially if it’s going to mean the difference between releasing your game or not.

So, while many people may steer you away from singletons, and while there are definitely good reasons not to use them, if you understand the risks and use them carefully, they can be very useful as a tool to help you to manage your game more easily.

Now it’s your turn

Now I want to hear from you.

Are you using singletons in your game?

Have they helped you, or have they made your project more difficult to work with?

And what experience do you have with singletons that could help someone else decide if using them is right for their project?

Whatever it is let me know by leaving a comment.

John French profile picture

by John French

Game audio professional and a keen amateur developer.

Get Game Development Tips, Straight to Your inbox

Get helpful tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

How this content was created

This article was written using first-hand research and experience, without the use of AI. For more information on how Game Dev Beginner articles are written, see my writing policy.

Comments

  1. thank you so much sir for this topic,i hope you will post new tutorials as it seems that you stopped for a while.

    1. Author

      You’re welcome. Don’t worry, more tutorials are on the way, just working on a special project first. If you’re subscribed to the newsletter, you’ll hear about it soon.

  2. keep it up man, love your way of explaining difficult topics!

  3. Thank you. Every time you post a new article. The content is amazing. I think it’s just a little bit but there’s still a lot I haven’t learned. Thank you

  4. Great blog, thank you!
    I’m quite new to gamedev and singleton has been useful for most cases but sometimes i scratched my head trying to find where is the function being called haha.

  5. I’ve heard of singleton some time ago and today I was wondering if it’s a good idea to use singleton in a small project I’m working on. Now I think I’ll use it. Thanks for the great explanation of the topic 🙂

  6. Nice article. I do have a question about assemblies though. Won’t using a master singleton that has GetComponentInChildren cause your master singleton’s assembly to depend on tons of scripts, essentially making assemblies unusable?

    My project is big enough that assemblies have to be employed to speed up compile times.

    1. Author

      Thanks! Unfortunately, I don’t have an answer for you on using Singletons with assemblies. However, singletons are pretty common in Unity, so someone in the forums can probably help you with this.

  7. Hi John. Great article (as are all your articles – you’re very talented at explaining complex concepts in a simple, yet still detailed, way).

    For the master singleton, would the sub-systems also be singletons? Or is the idea that the master singleton is the one and only singleton, and its sub-systems are just normal game objects and classes?

    1. Author

      Thanks Adam, so yes in that example only the Master is a singleton and the systems it links to are just regular scripts.

  8. great post!!
    i was drawing a class diagram. but i conflict so many singletones.
    for example, SoundManager, UIManager, DataManager, NetworkManager, ResourceManager, PoolManager,,

    when I was thinking of make similar master singletone, i saw this post.
    I will take note. thank you.

  9. Really great article!
    I’m making Portfolio for my game and was having difficulties for making design patterns. I always thought using singleton is against OOP so never to use them. but I guess understanding when to use it, I can use some of it for my project. It would greatly reduce my time.

  10. Thanks again.

    I can say from the other hand that also not using them can get things really nasty with endlessly fetching the same objects/scripts all over…

    Intuitively (as I never tried it) while understanding the risks at scale, I think that a Singeltone + paranoia (just a bit) would end up being much easier to manage if I’ll include some “collision detection” in it for all the incoming requests.

    But who knows, gonna be fun trying anyhow

  11. Hello! Thank you for your article. Could you please tell, alternatives to Singleton pattern? I’ve read an article about Service Locator and it was stated there that it could also lead to major issues. Right now I am sort of paralyzed being new to Unity and cannot make up my mind about how to approach my project. Is there a safe pattern of organizing elements of the game?

    1. Author

      Hi Alex, I’m not much of an authority on the different design patterns (try this site for that) but in my limited understanding I think that a good way to do it as a beginner, is to think about what it is you’re trying to build, pick an approach that will probably work, based on the strengths and weaknesses of different methods, and what other people have done to make similar games, and then just run with it.

      Realistically, you might end up using parts of one pattern to do one thing and parts of another to do something else but, generally, you’re not going to really know if something is working for you until you start doing it. And while I imagine that strict adherence to a framework is probably pretty important to big teams and large-scale projects, if you’re on your own, and especially if you’re new to Unity, it’s probably better to just focus on what works for you and what kind of works for the project and, so long as it won’t cause you big problems later, try not to overengineer it. Hope that helps!

  12. Hey John,
    How does Destroy(this) actually destroy the duplicate gameobject ?
    It should be destroying only the script component attached to the gameObject. Right ?

    1. Author

      You’re right, it doesn’t destroy the game object, it destroys the script. This would generally be safer if there’s a chance you’ve added the same script twice, for example, but if it’s on an object on its own, or if you know that the whole object must not be duplicated, you could use Destroy(gameObject) instead.

  13. I don’t get the argument against singletons making it harder to change how it functions, that seems like it will require changes no matter what. You say if you decide that your PlayAudio() function needs to include volume or needs to be able to play from an array for example, but no matter how you slice it, even if it wasn’t a singleton you’d have to rewrite all the places the relied on that functionality as well. I do not see the drawback. Do you know of another way of explaining it so I can understand?

    For example if I were in that situation I would just add another couple functions PlayAudioWithVolume() and PlayAudioFromList(), then go to all the places that were calling PlayAudio() to now call one or the other with the new data they need passed in. No matter what you need the new data anyway so you will always end up rewriting/updating all the places that use these functions anyway.

    I came to this article to try to understand all the hate for singletons because from my perspective they are essential, especially for a multiplayer game. Because things like players don’t exist in the scene at the start it’s impossible to hook things up via inspector references and it would also get pretty hairy to connect things via other ways like GetComponent, if they aren’t attached in any way in the hierarchy that won’t work. FindObjectOfType is also a bad approach. Service Locator seems like a decent alternative to it but it in it of itself is actually just a singleton.

    I’m just confused cause they are hated so but I’m trying to figure out how I would even work around not having singletons.

    1. Author

      Thanks Kyle, so yes that’s the drawback really. That the connection to the singleton is hardcoded from anything that uses it. Which can be a problem if you need to change something but, as you said, that may be inevitable anyway. I think that a lot of the bad press around singletons comes from people using them because it’s an easy method, instead of the right method for what they’re trying to do. And I think that can sometimes get in the way of when a singleton is actually really useful. Personally, I think that singletons are fine for systems that are unique and that need to exist in the scene. Like an Audio Manager. However, if they don’t need to exist in the scene, then it’s worth considering something like scriptable objects instead. Hope that helps, feel free to get in touch at [email protected] if you want to discuss it any further.

  14. Great article, thanks! I’m a bit confused though: if you dont make sure the gameobject to which youre singleton component is attached, doesnt get destroyed on scene load – would’nt all the singleton’s data be set to null on scene load? i.e rendering it useless. That’s what happening to me at least

    1. Author

      Well it depends on how you want to use it. Typically singletons work well for ‘global’ systems that need to exist in the scene. So you might destroy them when loading a new scene or you might not, particularly if the objects or scripts they reference also aren’t destroyed. But if you want to hold data that persists between scenes you might do better with a scriptable object anyway.

  15. I’m trying to get two Singletons to trade info:
    gun sends ammo request to Inventory, Inventory deducts ammo and sends gun what it has.
    Inventory is on the parent and gun is on its’ child

    I keep getting a Null Reference Exception for Inventory returning to gun, despite the code being virtually identical. Any ideas?

    1. Author

      Normally the point of a singleton is that they don’t need to have a hierarchical relationship so you normally wouldn’t use singletons like this, especially if you might have more than one gun or inventory. If you’re happy to share your code, email me at [email protected] and I’ll see if I can help.

Leave a Comment