Singleton Event Manager

So for my learning project, I’m making a point and click adventure. I’ve been rewriting most of the code a number of times now, since I’m learning new things on a regular basis.

The latest thing I’ve come across is singletons and the event system. Now I think they go great together, so I figured I’d create an event manager singleton (the one with the static instance) that would sit in a persistent scene and load in my game scenes additively. When an item loads, it subscribes to the appropriate events on the event manager and it would manage the communication between the different items and the actions the player takes. Same way, it unsubscribes, when a different scene gets loaded.
Easy enough, it seems to work quite well.

Now I’ve read a bit more on the use of singletons, and it seems there’s basically 2 sides: One that thinks singletons are a gift by god and the other that tell you your code will catch fire if you use them.

So what’s the deal here? I mean I could see overusing this becoming a problem, but I believe the way I’ve set it up, it should work quite nicely. Then again, I am still trying to learn the best way of doing things. I think I still need the event manager as it is, so the only way I could see it work differently, would be to use getcomponent instead of the static instance. But that seems to be more semantic than anything else, there would still be a single(ton) instance of the event manager that handles all that.

Totally fine. Threads like this often get a lot of attention where people bash their heads together pointing out the subtle reasons why one approach or another is potentially non-ideal in specific cases. But in general, there’s no reason to go out of your way to avoid using singletons. I’m 100% sure that the singletons I’ve authored could be critiqued as having some potential problems to them, where I’m not 100% sticking to separation of concerns, etc. But it all works fine, which is pretty much the only thing that matters. If you were writing some software that was being used by others, or would be maintained for a decade, sure, maybe you’d belabor this a bit more. But you’re making a game. Don’t get too caught up second guessing your approaches if they work.

Also, it’s worth mentioning: Your approach of keeping your singleton in a scene, and then additively loading other scene seems a little odd to me. You know you can keep singletons, or any object, alive indefinitely if you call DontDestroyOnLoad() on it? You don’t need to have a dedicated scene for your singletons, nor do you have to be worried about your singletons being destroyed if you call LoadScene.

1 Like

Write your game structure and execution order from start to end, then decide where singleton should go and blabla.

So it’s really more a “depends on how you use them” sort of thing? That I can agree with.

I’m using a persistent scene, because it’s also where my UI is stored, and it feels cleaner to do the additive loading rather than dragging the objects with me all the time.

Pretty much. You’ll always have people recommend you do things a different way, but that’s often because the other way worked well for them, and they might have different needs in their project than you do in yours. An approach becomes “bad” when it starts introducing bugs or making it too hard to build or maintain your game. Otherwise, there’s probably a very strong argument for just using the simplest solution you can come up with that meets your current needs, and just be ready to modify it later if you discover a problem, or your needs change.

As for the UI, your UI could also use DontDestroyOnLoad. Obviously use whatever approach you want, but I think it’s pretty nice to be able to do a hard LoadScene whenever I want without having to worry about destroying certain things. I’m not recommending you change your approach, but just wanted to make sure you were aware of the DontDestroyOnLoad option.

2 Likes

Thank you. Yes, I know of DontDestroyOnLoad, and I even tried it. It feels… weird. I can’t even place it. Like casting something into the void hoping it will make it to the other side. It’s probably silly, but it just feels a lot cleaner to me to have things in a persistent scene.

I’m not trying to convince you that you should use DontDestroyOnLoad. But I will try to convince you that it’s a pretty clean and safe approach. It’s the basis of many of the systems I use in my game. Rather than something being cast into the void, Unity actually organizes them nicely in the Hierarchy view while the game is running. Here you can see the main scene (collapsed). Below it, you’ll see the “DontDestoyOnLoad” pseudo-scene that Unity creates to hold any DontDestroyOnLoad objects:

6078084--659427--upload_2020-7-10_22-52-3.png

Using this DontDestroyOnLoad functionality is very simple, and I’ve never had any problems or hard-to-trackdown bugs because of it, despite leaning pretty heavily on it.

Anyway, I’m not trying to talk you into it. Just keep it in the back of your mind as an option for now or the future. It’s very useful.

1 Like