Search Unity

Is using static variables a bad idea for referencing DontDestroyOnLoad objects?

Discussion in 'Scripting' started by bradypp, Sep 10, 2019.

  1. bradypp

    bradypp

    Joined:
    Jul 9, 2019
    Posts:
    8
    I currently instantiate a game manager prefab with all the scripts I need to persist across scenes in awake then use DontDestroyOnLoad. I do this as an alternative to using singleton or static scripts but I'm struggling to decide on how to get references to these scripts in a performant way. I've been using FindObjectOfType which isn't ideal so I'm wondering if storing references to these scripts in static variables is a good idea.

    For example in the Time Manager script I'd have:

    Code (CSharp):
    1. public static TimeManager timeManager;
    2. void Awake()
    3. {
    4.      timeManager = this;
    5. }
    I can then access that script with TimeManager.timeManager. It's obviously convenient but I'm wondering if the downsides to this are the same as using a singleton and if I just might as well use a singleton if I'm going to do this. Thanks for any help.
     
    Last edited: Sep 10, 2019
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,511
    ....is this...not a singleton?
     
    Joe-Censored likes this.
  3. bradypp

    bradypp

    Joined:
    Jul 9, 2019
    Posts:
    8
    I guess it is a singleton. I've just never seen it done this way before so didn't think of it as one.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    1,072
    A "singleton" is basically just anything that you only ever have one of. A static variable or function is the typical way to provide access to that single instance.

    There are some downsides to singletons, but I think they are often a practical choice for Unity games, especially if you are learning programming as you go.
     
    Joe-Censored likes this.
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    6,281
    Using a static reference as you're doing, or getting a reference using FindWithTag, are probably the two most common ways of handling this.
     
  6. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    633
    I'm not a fan of singletons. Personally, I use scriptable objects for my managers and create the asset in a resources folder. If I need to access a manager, then I can just load it from resources.

    For example, when my player takes damage, it is reported to the player manager which is a scriptableobject. The ui ect can subscribe to an event on that manager and then do what they need to when the players health changes.
     
  7. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    1,072
    This still sounds like a singleton to me. What do you see as the advantages of doing it this way?
     
  8. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    633
    It isn't a singleton and a scriptable object cannot be placed in a scene or on a gameobject. I use the scriptable object as a middleman so there are no dependencies. The scriptable object is always available so if I put a player in a scene without a UI, the player class doesn't care and vice versa.

    I mostly use events. So when the player's health changes, the player class reports the change to the player manager SO which then fires an event with the health details. Any class can listen to that event but the player manager doesn't care if no one is listening.

    Watch this great talk on SO's for more info -
     
  9. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    1,072
    So how is this better than a plain old C# object, with no Unity bits at all?
     
  10. persy

    persy

    Joined:
    Feb 24, 2016
    Posts:
    1
    ScriptableObject over plain C# singleton also gives you serializable and UI-inspectable state out of the box. You may want it in some cases
     
  11. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,158
    I think no. Singleton responsibility is to limit user to single instance. Static field is a way to store & access singleton instance reference, but it is not a part of template itself. And the code presented by OP isn't a singleton because it is not limiting to single instance. He may create 100+ such TimeManagers in any scene. To be singleton, class must not allow creation of two and more instances, but this class does not fullfill this requirement.
     
  12. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    1,072
    Building mechanisms to prevent your class from being used in unintended and unsafe ways might be a good idea, but I would describe a class that lacks such mechanisms as "an unsafe implementation of X" rather than "not an X."

    In my view, design patterns are best understood as fuzzy strategies for organizing your code, not a list of technical requirements to check off.