I use singletons regularly and love them for global features. The example of the Player as a singleton is valid but I use a singleton PlayerManager which will hold either 1 or more players so it can be expanded. I also declare my singletons with a simpler approach than shown. The Awake checks that the static instance variable is null and asserts if it isn't. If you have multiple instances in multiple scenes then you have broken the singleton approach already. You "could" have differently set up singletons across scenes if they don't use prefabs. You will have also loaded in multiple instances and so are wasting loading and destroying time. If you need them in multiple scenes then they should all live within a single prefab that is conditionally loaded in each scene. Then any scene that needs them just has this conditional loader class in it, which isn't a singleton, but checks for the prefabs existance.
Instead of singletons I mostly use static classes for Data management and events. Combined with static methods, I have very strong control over what data can be edited. Besides that I worked with another programmer on a custom debug system that always identifies which scripts access the static class to keep everything transparent.
I do use Singletons sometimes. Mostly to get to the dependency injector, but also for constants. Generally, if you feel singletons are the best solution then you probably don't know the best way of solving the problem. They are however, a very adequate and sometimes quicker to implement solution. But time spent developing a solution is infinitesimal compared to the time you maintain your code, so unless you're not planning on continuing the project the technical debt will eat up the time saved in a fairly swift order.
Great video! I really appreciate your detailed explanation of singletons. It was easy to follow along and understand the concept. Your analysis of their pros and cons was insightful. Regarding the your question. I did use them a while back for some projects but while Singletons can be convenient in certain scenarios, imo. Scriptable Objects offer more flexibility and maintainability in larger projects. They allow for better encapsulation and decoupling, making it easier to manage and modify data without tightly coupling it to specific classes. Maybe that would be a nice Video topic too =]. Best regards
The biggest risk with singletons is that you can't easily make unit tests, if you can't make unit tests you won't make unit tests, if you don't have unit tests you are more likely to create edge cases and create bugs when you alter code. Tests also help because they document your code in an absolute manner, and when writing tests you focus on thinking about edge cases, whereas while implementing functionality you focus on how to make it "do the thing." Adding tests is like adding a whole extra team of QA, even if you're a solo dev it helps you not only by catching mistakes but by offloading the necessity to think of *every* little system at once when you make changes. I was the solo dev for a 300k lines of code business system. Thanks to having good coverage with unit tests and working with TDD/BDD I could swiftly add features without worrying if I was about to make the business lose money or customers because of an edge case or bug. The time spent writing the tests is negligible compared to the amount of time I saved, and that's not even considering the peace of mind it gave me. PS, [SerializeField] allows you to completely avoid any and all Singletons. To swap away from an existing Singleton you can just [Obsolete] the Instance property, then add the reference and apply it in the editor. You can also select many components at once and drop the reference to all of them at once, so having thousands of instances of a component isn't an obstacle to doing this.
Sometimes you have to access a Singleton between different scenes. In that case you can not reference them in the editor but you can easily access them by code. Yes, there are some other tricks like the references trough scriptableobjects and all, but this one is WAY simpler to understand, and sometimes, to work with. Just know the risks, and choose the right tool for the right job.
I find refactoring a lot of unity monobehaviour style code to be unit-testable can be quite a lot of work that involves extracting a ton of the logic out into pure c# classes. "the time spent writing the tests is negligible" I am struggling with refactoring code i've inherited and the value of refactoring to be testable vs leaving as is. any thoughts?
I have a small number of singletons. I'm currently a solo dev and I've been very focused on thinking ahead to make things more manageable long term, so when I started I was in the camp that it's best to avoid using them. However I realized that there is a case where they are the best option for my goal. Each singleton is very specifically a system that needs to interact with a large number of indeterminate objects and the data it holds must be the same across all those objects. For instance, I have a turn based tactical combat system and so the combat system itself is a singleton that registers what entities are in combat, whos turn it is, and what's happening to everything before/after/during those turns. If I ever wanted to let multiple players be in separate combat instances I'd need to rethink how this was done, however that is so far beyond the scope of what i'm trying to do and honestly I can't think of a reason I'd want to include multiplayer in such a way with a turn based tactical game. However, I think if I was working with a large team with managers and publishers making unreasonable requests I think I would still find a non-singleton solution just in case that scope changed. Edit: Just to add, I have also thought about using scriptable objects for this scenario as well since you can accomplish the same things, but realized that the one drawback compared to a singleton is if I have a script that DOESN'T exist in the scene but still needs the information, a singleton can actually do more for you. This is an edge case, but one I actually ran into fairly recently.
For something like health, the simplest way to do it (without a singleton) is to create ScriptableObject variable. Just attach it to the player and decrease the value of the ScriptableObject. You can then simply stick it wherever you need to read the value.
Amazing video as usual! I found your channel a few days ago but I think I’ve already watched all your videos haha. Anyway, I have a question possibly somewhat related to singletons: how would you manage gameplay loops? By that, I don’t mean the literal Update() method frame by frame, but how to manage gameplay elements (spawns, events) that can happen on a loop. A dynamic tower defense game is probably the best example? How would you design the *core* manager so you can later extend it with enemy spawns, waves, multiple levels, randomizations. How would you manage the states, events, data, etc. I don’t think I’ve found any tutorials that discussed this, they’re not even mentioned in the extensive ones. But again thank you so much for your videos! Edit: I’m a bit embarrassed to found out that Brackeys already made a complete tower defense tutorial a long time ago, but hearing your take would still be pretty cool!
Really hoping you continue to make tutorials, yours are by far the highest quality and information dense. Most other youtubers brush on the basics of a topic but you always make sure to go in depth.
i think i found better way to instantiate instance. No need to instantiate in Awake(), we will instantiate on the instance first access by using getter property. public static Instance { get { if ( instance == null ) instance = FindObjectOfType(); return instance; } } this way will solve one of my problem: null instance reference. Some time i want to access instance of class A in class B in OnEnable(), but OnEnable in class B run sooner Awake in class A which make instance == null
As far as I understand it, it is possible for a script's On Enable to be called before a different script's Awake. But, On Enable isn't really meant for this type of initialisation anyway. You'd be better off using Start, which is always called after Awake. Which is why you might typically put self-initialisation in Awake (one-time set up) or On Enable (activation tasks when turning the object on and off) and then set up external references in Start. I wrote an article on it if that's any help: gamedevbeginner.com/start-vs-awake-in-unity/
@@hoangtongvu9952 Ah I see! In that case, use the Script Execution Order settings to make sure your Singleton's awake function is called before any of the others.
@@GameDevBeginner i will try that later, thanks :3 anyway, you use awake function to get components in gameObject, right? my Awake only used to create singleton, i get component before gameplay by using reset button, it may make more code line but it is a convinient way to get components
it's the first time im goin to use singleton but i believe is the only solution in this case right now im working on game and i want some way many off my codes to know if the menu is open or closed 🔐 in the order to do stuff like disable the button wean the menus are open for example so in my case i need boolean evry code i wand do something wean the boolean is on or off. because this is boolean and wand this boolean to apply in all my sean i don't really afraid to use Singletons. also i will my my code whay simpler because the alternative is to have direct access to this menu code and have at least code to have direct access and have the biggest problem is it in the future it may end make code that i wand to disable the buttons and not able to do that because i don't have direct access however with Singletons if use singleton it fix this issue. i know the menus in my game have only 2 states and i wand thos menus to able to effect all my sean on the codes i wand to effect so it's the best option for my to use singleton if not my only option.
I use singletons regularly and love them for global features. The example of the Player as a singleton is valid but I use a singleton PlayerManager which will hold either 1 or more players so it can be expanded. I also declare my singletons with a simpler approach than shown. The Awake checks that the static instance variable is null and asserts if it isn't. If you have multiple instances in multiple scenes then you have broken the singleton approach already. You "could" have differently set up singletons across scenes if they don't use prefabs. You will have also loaded in multiple instances and so are wasting loading and destroying time. If you need them in multiple scenes then they should all live within a single prefab that is conditionally loaded in each scene. Then any scene that needs them just has this conditional loader class in it, which isn't a singleton, but checks for the prefabs existance.
Loved the visual explanation! Thank you!
Subscribed! Your gamedevbeginner blog is awesome! Thanks bro!
No, thank you!
Instead of singletons I mostly use static classes for Data management and events. Combined with static methods, I have very strong control over what data can be edited. Besides that I worked with another programmer on a custom debug system that always identifies which scripts access the static class to keep everything transparent.
I do use Singletons sometimes. Mostly to get to the dependency injector, but also for constants.
Generally, if you feel singletons are the best solution then you probably don't know the best way of solving the problem. They are however, a very adequate and sometimes quicker to implement solution. But time spent developing a solution is infinitesimal compared to the time you maintain your code, so unless you're not planning on continuing the project the technical debt will eat up the time saved in a fairly swift order.
Very helpful video , this channel will be no.1 soon if video comes regularly Good luck
Great video! I really appreciate your detailed explanation of singletons. It was easy to follow along and understand the concept. Your analysis of their pros and cons was insightful.
Regarding the your question. I did use them a while back for some projects but while Singletons can be convenient in certain scenarios, imo. Scriptable Objects offer more flexibility and maintainability in larger projects. They allow for better encapsulation and decoupling, making it easier to manage and modify data without tightly coupling it to specific classes. Maybe that would be a nice Video topic too =]. Best regards
Singleton sounds like a good use for an Input Manager.
The biggest risk with singletons is that you can't easily make unit tests, if you can't make unit tests you won't make unit tests, if you don't have unit tests you are more likely to create edge cases and create bugs when you alter code. Tests also help because they document your code in an absolute manner, and when writing tests you focus on thinking about edge cases, whereas while implementing functionality you focus on how to make it "do the thing."
Adding tests is like adding a whole extra team of QA, even if you're a solo dev it helps you not only by catching mistakes but by offloading the necessity to think of *every* little system at once when you make changes. I was the solo dev for a 300k lines of code business system. Thanks to having good coverage with unit tests and working with TDD/BDD I could swiftly add features without worrying if I was about to make the business lose money or customers because of an edge case or bug.
The time spent writing the tests is negligible compared to the amount of time I saved, and that's not even considering the peace of mind it gave me.
PS, [SerializeField] allows you to completely avoid any and all Singletons. To swap away from an existing Singleton you can just [Obsolete] the Instance property, then add the reference and apply it in the editor. You can also select many components at once and drop the reference to all of them at once, so having thousands of instances of a component isn't an obstacle to doing this.
Sometimes you have to access a Singleton between different scenes. In that case you can not reference them in the editor but you can easily access them by code.
Yes, there are some other tricks like the references trough scriptableobjects and all, but this one is WAY simpler to understand, and sometimes, to work with.
Just know the risks, and choose the right tool for the right job.
@@ligofleyens9131 Or be like me and use your scriptable objects as singletons 😎
@@ligofleyens9131 A singleton between scenes. Are you talking about a singleton that also has DontDestroyOnLoad(this);?
I find refactoring a lot of unity monobehaviour style code to be unit-testable can be quite a lot of work that involves extracting a ton of the logic out into pure c# classes. "the time spent writing the tests is negligible" I am struggling with refactoring code i've inherited and the value of refactoring to be testable vs leaving as is. any thoughts?
I have a small number of singletons. I'm currently a solo dev and I've been very focused on thinking ahead to make things more manageable long term, so when I started I was in the camp that it's best to avoid using them. However I realized that there is a case where they are the best option for my goal.
Each singleton is very specifically a system that needs to interact with a large number of indeterminate objects and the data it holds must be the same across all those objects. For instance, I have a turn based tactical combat system and so the combat system itself is a singleton that registers what entities are in combat, whos turn it is, and what's happening to everything before/after/during those turns.
If I ever wanted to let multiple players be in separate combat instances I'd need to rethink how this was done, however that is so far beyond the scope of what i'm trying to do and honestly I can't think of a reason I'd want to include multiplayer in such a way with a turn based tactical game. However, I think if I was working with a large team with managers and publishers making unreasonable requests I think I would still find a non-singleton solution just in case that scope changed.
Edit:
Just to add, I have also thought about using scriptable objects for this scenario as well since you can accomplish the same things, but realized that the one drawback compared to a singleton is if I have a script that DOESN'T exist in the scene but still needs the information, a singleton can actually do more for you. This is an edge case, but one I actually ran into fairly recently.
This is easily the best explanation.
Nice video dude 👏. we need more about dependency injection.
For something like health, the simplest way to do it (without a singleton) is to create ScriptableObject variable. Just attach it to the player and decrease the value of the ScriptableObject. You can then simply stick it wherever you need to read the value.
Can you make a video about colision detection with physic, raycast,...
Singletons opens my eyes before i just use getcomponent for everything and this become so handy and more clear to read
Mirror's Network Manager is a singleton. Sometimes it gives me a headache but I think it was the right solution
Thank you so much for your great video.
You're welcome!
ty for video Very helpful
Hi please make a tutorial about vector s and their functions like vector3.lerp etc
Amazing video as usual! I found your channel a few days ago but I think I’ve already watched all your videos haha. Anyway, I have a question possibly somewhat related to singletons: how would you manage gameplay loops? By that, I don’t mean the literal Update() method frame by frame, but how to manage gameplay elements (spawns, events) that can happen on a loop.
A dynamic tower defense game is probably the best example? How would you design the *core* manager so you can later extend it with enemy spawns, waves, multiple levels, randomizations. How would you manage the states, events, data, etc. I don’t think I’ve found any tutorials that discussed this, they’re not even mentioned in the extensive ones.
But again thank you so much for your videos!
Edit: I’m a bit embarrassed to found out that Brackeys already made a complete tower defense tutorial a long time ago, but hearing your take would still be pretty cool!
Thank you! I'm going to defer to Brackeys' better judgement on this one, my advice is to do whatever that video says.
Really hoping you continue to make tutorials, yours are by far the highest quality and information dense. Most other youtubers brush on the basics of a topic but you always make sure to go in depth.
@@werewolfdragon4740 Thanks so much. Will do!
Clearly than that it is impossible, thank you very much
i think i found better way to instantiate instance. No need to instantiate in Awake(), we will instantiate on the instance first access by using getter property.
public static Instance
{
get
{
if ( instance == null )
instance = FindObjectOfType();
return instance;
}
}
this way will solve one of my problem: null instance reference. Some time i want to access instance of class A in class B in OnEnable(), but OnEnable in class B run sooner Awake in class A which make instance == null
As far as I understand it, it is possible for a script's On Enable to be called before a different script's Awake. But, On Enable isn't really meant for this type of initialisation anyway. You'd be better off using Start, which is always called after Awake. Which is why you might typically put self-initialisation in Awake (one-time set up) or On Enable (activation tasks when turning the object on and off) and then set up external references in Start. I wrote an article on it if that's any help: gamedevbeginner.com/start-vs-awake-in-unity/
@@GameDevBeginner the reason why i want to get instance reference in OnEnable is subscribing events( unsub in OnDisable)
@@hoangtongvu9952 Ah I see! In that case, use the Script Execution Order settings to make sure your Singleton's awake function is called before any of the others.
@@GameDevBeginner i will try that later, thanks :3 anyway, you use awake function to get components in gameObject, right? my Awake only used to create singleton, i get component before gameplay by using reset button, it may make more code line but it is a convinient way to get components
it's the first time im goin to use singleton but i believe is the only solution in this case
right now im working on game and i want some way many off my codes to know if the menu is open or closed 🔐 in the order to do stuff like disable the button wean the menus are open for example so in my case i need boolean evry code i wand do something wean the boolean is on or off.
because this is boolean and wand this boolean to apply in all my sean i don't really afraid to use Singletons. also i will my my code whay simpler because the alternative is to have direct access to this menu code and have at least code to have direct access and have the biggest problem is it in the future it may end make code that i wand to disable the buttons and not able to do that because i don't have direct access however with Singletons if use singleton it fix this issue.
i know the menus in my game have only 2 states and i wand thos menus to able to effect all my sean on the codes i wand to effect so it's the best option for my to use singleton if not my only option.
May I ask on what software you are using to develop these animations? I am using Blender.
I mostly just key frame everything in Davinci Resolve. There's probably a better way but that's what I've been doing.
What are alternative to singleton?
I think for use in AudioManager it is ok?
I think Audio Manager is an ideal use case yes
i went anti-singleton and now i have an event channel salad plz help
good video, but i suggest that you try not to repeat yourself too much, even you're just trying to make some more clear it gets repetititve