1
\$\begingroup\$

I've heard a lot of people say singletons are bad practice and an 'anti-pattern', like here, this answer this article and here. However, a lot of the reasons I've read about seem to be to do with dangers in their creation, them not being thread safe, difficult to destroy safely etc. But in unity where there are functions such as awake() and start() which are (as far as I'm aware) guaranteed to only be called once, are they unsafe to use?

\$\endgroup\$
  • \$\begingroup\$ I use a Singleton in my projects; Cognizer used one. It's called "SharedData" and contains anything different parts of the game need to know. Like the MenuSystem finds out the user wants to play on Expert, so that goes in SharedData so the Game part can find it. But this is very much an opinion-based question. \$\endgroup\$ – Almo Apr 27 at 18:57
  • 1
    \$\begingroup\$ There are a lot of opinions around singletons, so I'm not sure this is a question we can answer objectively - it's more about coding style, or weighing whether particular considerations apply to your case. Game Programming Patterns has a good article on them, pointing out a lot of the trouble comes from the fact that we reach for singletons for lots of different reasons: enforced uniqueness, global access, lazy initialization. If you only need one of those, the others can become liabilities. So, just understand clearly what you're after. \$\endgroup\$ – DMGregory Apr 27 at 18:59
  • 1
    \$\begingroup\$ I don't think this question is opinion-based. If someone says "singletons are bad", there should be a reason for them to say that, which in turn should be backed by facts or experience for it to be a valid answer anyway. \$\endgroup\$ – S. Tarık Çetin May 3 at 14:41
  • \$\begingroup\$ @S.TarıkÇetin the trouble is there are good objective reasons why someone would want to avoid singletons in some circumstances. There are also good objective reasons why singletons are useful and safe in some circumstances. So there's not necessarily a "correct" answer here - whether the pro- evidence or the con- evidence wins out in a particular situation involves subjective judgement calls, based on the particulars of the case in question. \$\endgroup\$ – DMGregory May 6 at 20:28
  • \$\begingroup\$ Voted to close because the question had three votes to close on it. \$\endgroup\$ – Vaillancourt Jul 10 at 1:44
1
\$\begingroup\$

You have stumbled onto a controversial topic in the programming world. Most people dislike singletons, but we game developers tend to be a bit more friendly towards them. There are pros and cons to singletons.

My answer is specific to Unity, and covers maybe 1% of the topic.

In Unity, Singletons are very useful. Let's say you have a manager class that you want to be globally accessible. You could make a static class instead - but then you lose access to Unity messages, Awake, Start, Update, etc., which are the heart of MonoBehaviours.

You mentioned thread safety - Unity is single threaded. So you will not run into these problems (unless you explicitly break off the main thread).

So why are they so bad? There are much better articles, like the ones you linked, which explain it much better than I can.

But if you stay disciplined, Singletons can make game development much easier. However, since you don't have any of the safeguards that you gain with other design patterns, it is easy to fall into the traps that Singletons present.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Awake() and Start() are called only once per object for reasons unrelated to Singletons. The single instance part of the singleton is fine, and its possible to make it thread safe and control how many things its keeping in memory because it never dies. It's the global accessibility that a lot of design pattern people dislike. Having a singleton in your code won't break it, but using them for everything can cause problems. Take it from someone who built a prototype held together by a half dozen singletons. I would slap that version of me if I could.

In large projects, it is important to 'decouple' your code. Overuse of Singletons promotes coupling code together. An example is a having an AudioSingleton that plays sounds. It looks like an awesome idea because then you can simple call AudioSingleton.Instance.PlaySound(GUNSHOT1); in your weapon code, and you're done. That's actually a huge problem. Now your weapons depend on the existence and functionality of the AudioSingleton.

It gets worse as the project grows, and the team grows. Every button press is a series of calls to different singletons, or one call to a massive singleton that sits at the center of your project, immovable and instable. Singletons lash together disparate objects and make it easier to cause problems and make finding problems more difficult.

There is a time and place for Singletons, but you need to be careful that you aren't solving a problem that just needs some carefully laid out wires and some solder with a global communications network. If you can avoid using a singleton by using something like the Observer pattern, you almost always should.

Also, even when you are working alone, your "team" grows over time, because you forget what you were thinking when you wrote your old code. In the years of solo development I've learned one thing: if you don't want to hate yourself write code like you're in a team.

I'd suggest reading this book: https://gameprogrammingpatterns.com/contents.html It put labels on all the patterns I blindly trying to use and explained their pros and cons with good examples.

| improve this answer | |
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.