Singletons in Unity (done right)

Sdílet
Vložit
  • čas přidán 29. 08. 2024

Komentáře • 44

  • @chrisb8772
    @chrisb8772 Před 6 měsíci +4

    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.

  • @lodyeg1
    @lodyeg1 Před 3 měsíci +3

    Loved the visual explanation! Thank you!

  • @alexdeegames
    @alexdeegames Před rokem +3

    Subscribed! Your gamedevbeginner blog is awesome! Thanks bro!

  • @systoliker6118
    @systoliker6118 Před rokem +1

    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.

  • @Sylfa
    @Sylfa Před rokem +1

    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.

  • @MySandy9
    @MySandy9 Před rokem +1

    Very helpful video , this channel will be no.1 soon if video comes regularly Good luck

  • @FreschGames
    @FreschGames Před rokem +1

    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

  • @Nev182mang
    @Nev182mang Před 3 dny

    Singleton sounds like a good use for an Input Manager.

  • @Sylfa
    @Sylfa Před rokem +12

    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.

    • @ligofleyens9131
      @ligofleyens9131 Před rokem +2

      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.

    • @wanderstudygames
      @wanderstudygames Před rokem +5

      @@ligofleyens9131 Or be like me and use your scriptable objects as singletons 😎

    • @MortonMcCastle
      @MortonMcCastle Před rokem

      ​@@ligofleyens9131 A singleton between scenes. Are you talking about a singleton that also has DontDestroyOnLoad(this);?

    • @unitydev457
      @unitydev457 Před 3 měsíci

      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?

  • @InzeDev
    @InzeDev Před rokem +1

    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.

  • @nathanrika4830
    @nathanrika4830 Před rokem

    This is easily the best explanation.

  • @AbdullahGameDev
    @AbdullahGameDev Před rokem +1

    Nice video dude 👏. we need more about dependency injection.

  • @aeliusdawn
    @aeliusdawn Před rokem

    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.

  • @bruhmanbruhmanzz
    @bruhmanbruhmanzz Před rokem +2

    Can you make a video about colision detection with physic, raycast,...

  • @branidev
    @branidev Před rokem +1

    Singletons opens my eyes before i just use getcomponent for everything and this become so handy and more clear to read

  • @arturochavezsendra2863

    Mirror's Network Manager is a singleton. Sometimes it gives me a headache but I think it was the right solution

  • @aggemcore
    @aggemcore Před rokem

    Thank you so much for your great video.

  • @price634
    @price634 Před 6 měsíci

    ty for video Very helpful

  • @alin98988
    @alin98988 Před rokem +1

    Hi please make a tutorial about vector s and their functions like vector3.lerp etc

  • @georgepitoy5426
    @georgepitoy5426 Před rokem

    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!

    • @GameDevBeginner
      @GameDevBeginner  Před rokem

      Thank you! I'm going to defer to Brackeys' better judgement on this one, my advice is to do whatever that video says.

    • @werewolfdragon4740
      @werewolfdragon4740 Před rokem

      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.

    • @GameDevBeginner
      @GameDevBeginner  Před rokem

      @@werewolfdragon4740 Thanks so much. Will do!

  • @regys9521
    @regys9521 Před rokem

    Clearly than that it is impossible, thank you very much

  • @hoangtongvu9952
    @hoangtongvu9952 Před rokem

    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

    • @GameDevBeginner
      @GameDevBeginner  Před rokem +1

      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
      @hoangtongvu9952 Před rokem

      @@GameDevBeginner the reason why i want to get instance reference in OnEnable is subscribing events( unsub in OnDisable)

    • @GameDevBeginner
      @GameDevBeginner  Před rokem +1

      @@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.

    • @hoangtongvu9952
      @hoangtongvu9952 Před rokem

      @@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

  • @watercat1248
    @watercat1248 Před 2 měsíci

    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.

  • @lodyeg1
    @lodyeg1 Před 3 měsíci

    May I ask on what software you are using to develop these animations? I am using Blender.

    • @GameDevBeginner
      @GameDevBeginner  Před 3 měsíci +1

      I mostly just key frame everything in Davinci Resolve. There's probably a better way but that's what I've been doing.

  • @mikhailhumphries
    @mikhailhumphries Před 5 měsíci

    What are alternative to singleton?

  • @ThunderaRafa433
    @ThunderaRafa433 Před 5 měsíci

    I think for use in AudioManager it is ok?

  • @sendark001
    @sendark001 Před rokem +1

    i went anti-singleton and now i have an event channel salad plz help

  • @rbarbeats
    @rbarbeats Před rokem +2

    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