It’s time to cover a topic that I’ve been avoiding for a long time.
And that’s the Singleton pattern.
But first, I’m gonna need some coffee.
Did I say coffee?
I totally meant a beer, and I’m gonna need it.
Alright, let’s do this.
The Singleton Pattern.
The Singleton Pattern is a design pattern that describes a class that is both globally
accessible and can only be instantiated once.
A classic example is the audio manager because, generally speaking, it’s something you’ll
need to access in a lot of scripts and that you’ll want to make sure only exists once
in any given scene.
That doesn’t sound too bad, right?
So why have I been avoiding Singletons for so long?
Well, if you’re listening carefully, you may have picked up on something that makes
the Singleton Pattern different from other design patterns — that it has two technical
requirements.
One, a singleton must be restricted to a single instance and two, it must also be globally
accessible.
Now, that might not seem like a big deal at first.
But together these two requirements offer a tempting upfront value that is vastly outweighed
by the pain they can cause in the long run.
Let’s explore why by taking a look at each requirement on it’s own.
Imagine a simple project with a Player, Game Manager, and some classes to handle basic
tasks, like displaying health on the UI.
In this example, the Game Manager is responsible for ending the game when the player dies,
so it has a reference to the Player class.
But how does it get access to the Player in the scene?
Now, there’s actually a few ways to answer that question, and I have a video that covers
each one.
But, for the sake of this video, just know that we can either give the Game Manager a
reference to the Player by setting an exposed property from another script or the editor,
or we can have the Game Manager retrieve a reference to the Player for itself using,
you guessed it, a Singleton which is globally
The choice seems obvious, right?
Why would I bother constructing some fancy way to pass the Player around my code when
I could just turn it into a Singleton and get access for free?
What could possibly go wrong?
Well, as it turns out, quite a bit — just not at
The Singleton Pattern solves a very big unknown in Unity, which is how do you access other
scripts?
Or, another way to look at it is how do you fill your class dependencies?
Our Game Manager class depends on having a reference to the Player, which is obvious
because the Player class is part of its member variables.
Now, the effect I’m about to show you would be more dramatic in a real world scenario
where our Game Manager is a few hundred lines long, but if we remove this member variable
and access the Player singleton instance directly, we effectively hide the fact that the Game
Manager depends on having access to the Player, which can lead to all sorts of problems down
the road.
Because you may know what your code is doing the day you wrote it, but I promise you won’t
remember when you try to refactor it a week later.
Or worse, try to explain it to someone else who’s contributing to your project.
Hiding your class’ dependencies just makes everyone's lives more difficult in the long
run.
Now, admittedly, the pain of this might not seem obvious at first.
But when you consider that a Singleton can be accessed from anywhere, it isn’t hard
to conceive that you might actually start referencing them more and more throughout
your code — because, let’s be honest, it’s just so easy.
And with all those hidden dependencies comes a layer of complexity that should be avoided
as much as possible.
But that isn’t the only issue.
Here are two examples of our Player singleton being used in the previous project.
We’ve got a health bar and some logic to save the game.
Both access the player’s health, which is nice and consistent.
But what happens if we need to change how health works — say we want to add a special
type of Player that factors armor into its overall fortitude.
Well, any change we make to our singleton will affect the entire game because the Player
class is being referenced directly via the Singleton Instance variable.
However, if we refactor these classes and make the Player class a dependency, we can
fill that dependency with any class that derives from Player, such as a class called ArmoredPlayer
that implements the previously described functionality.
Again, these pain points are subtle but their effects snowball as your project grows.
What seems easy to change here in these discrete examples is much harder to do in a real world
scenario.
So much so, that you may find yourself exploring the Ballmer Peak to make it through your day.
Now, we’ve been talking about how using Singletons can be harmful to a project, but
their implementation, specifically in Unity, can be harmful, as well.
The other technical requirement of a Singleton is that it must be restricted to a single
instance.
To accomplish this restriction you’d normally hide your Singleton’s constructor by making
it private and then lazily instantiating a single Instance from the getter.
But this typically doesn’t work in Unity because most of your classes will probably
derive from MonoBehaviour.
And MonoBehaviours hide the constructor and allow anyone to instantiate them via Object
dot Instantiate.
So how do you restrict MonoBehaviours to a single instance?
Well, you can do it but, unfortunately, it requires some finagling to get it to work.
The concept is the same in that if the Singleton MonoBehavior doesn’t have a reference to
an instance yet, it’ll go ahead and create one of its own.
But, first it has to check the scene to confirm that one hasn’t already been created.
That’s because there are a couple ways that yourself or another developer can circumvent
the single instance restriction — by adding one or more instances directly into the scene
from the editor, or by calling Object dot Instantiate, like I mentioned before.
So, the getter will need to check the scene and grab the first instance it finds.
Notice I said, “the first instance”.
Because you could actually have multiple Singletons in your scene.
So MonoBehaviour based Singletons must destroy themselves if another one exists when they’re
created.
Which adds a bit of magic that can lead to some unexpected behavior.
For example, if your Singleton makes a call to DontDestoryOnLoad in order to persist through
scene changes, there’s a chance that there’ll be an instance of that Singleton in the new
scene.
And, what can happen is that, depending on the order they’re arranged in the hierarchy,
the wrong one could be deleted.
So, it works but it isn’t the best solution.
Now, where does that leave us?
Am I saying to never use Singletons again?
Well, let me put it this way.
I and many other developers get by just fine without them.
I could get into more detail about how using Singletons informs how you architect your
entire project and creates bad habits that cause you to tightly couple your code which
effectively destroys its flexibility in the long run.
But instead, let me leave you with some criteria to follow the next time you want to use a
Singleton.
One: does having more than one instance of your potential Singleton fundamentally break
your game?
I mean, would your code literally throw an exception and crash if you had more than of
them in a single scene?
Two: does it absolutely need to be accessed by different parts of your code?
And I’m not just talking about something like a player class that might get referenced
in the UI and the game manager, but does your potential singleton need to be accessible
by every nook and cranny of your code base?
And finally, three: will your singleton control concurrent access to a shared resource?
Think of a data manager that has the ability to open and close a save file, where simultaneous
access to the file would actually throw an exception.
If you keep those three criteria in mind, then you should have no trouble implementing
Singletons that actually provide long term value to your project.
Otherwise, I strongly suggest learning the techniques that you can use in Unity to safely
pass data around your game code.
And you can start with my video called “How to Access Variables From Another Script in
Unity”.
Pretty on those nose, right?
Give that a watch and let me know what you think in the comments.
Now, I know there are some pretty die hard Singleton users out there.
So if you think I missed the mark, let me have it.
Or if you agree with this video, then I’d love some positive feedback as well.
Welp, as always, thanks for watching and I’ll catch you in the next video.
Cheers.