Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Singletons seem broken

Discussion in 'Scripting' started by DoomDude99, Jan 10, 2020.

  1. DoomDude99

    DoomDude99

    Joined:
    May 11, 2019
    Posts:
    87
    I'm trying to create a singleton that holds two variables (latitude & longitude).

    Following

    https://answers.unity.com/questions/50716/how-to-make-a-global-variable-in-unity.html

    and

    http://wiki.unity3d.com/index.php/Singleton

    I wrote a class:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace GameNamespace
    4. {
    5.     public class CoordinatesContainer : Singleton<CoordinatesContainer>
    6.     {
    7.         public static float gLatitude;
    8.         public static float gLongitude;
    9.     }
    10. }
    However, unity complains that:

    Code (CSharp):
    1. error CS0246: The type or namespace name `Singleton' could not be found. Are you missing an assembly reference?
    Why? Isn't `Singleton` a builtin type?

    Removing the extension relationship:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace GameNamespace
    4. {
    5.     public class CoordinatesContainer
    6.     {
    7.         public static float gLatitude;
    8.         public static float gLongitude;
    9.     }
    10. }
    allows building, but am not sure this is good practice or even if it works.
     
  2. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Singelton isn't a built in type. You have to include the Singleton.cs script in your project. You also shouldn't use static variables with a singelton, since the purpose of the Singelton design pattern is expressly to avoid using static variables as much as possible. Instead, you would make those instance variables and refer to them through the singelton's Instance.
     
    nanqunchen, DoomDude99 and StarManta like this.
  3. APSchmidtOfOld

    APSchmidtOfOld

    Joined:
    Aug 8, 2016
    Posts:
    4,473
    What's the problem with public static variables (and public static functions)?
     
    DoomDude99 likes this.
  4. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    There's not a problem exactly, but the point of a Singleton is to have a class with non-static members that you access through a static variable. If everything's static in the class anyway then there's no reason to make it a singleton, you can just make it a static class:
    Code (csharp):
    1. public static class CoordinatesContainer {
    2.     public static float gLatitude;
    3.     public static float gLongitude;
    4. }
    5.  
    6. //.....in some other class:
    7. CoordinatesContainer.gLatitiude = 123;
    You don't even need to make it a static class, you can access static members just by using the class name of a normal class.
     
    DoomDude99 likes this.
  5. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    It's been a long time since my OO Design Patterns class, so the reasoning is a bit fuzzy. As far as I remember, the main reason to use a Singelton instead of static variables is that static variables are always in memory but you can destroy a singelton if you want to. I don't think that's a major concern, but if you really want to stick to the design principles set down by the gang of four, then they recommend singeltons instead of statics.

    EDIT: A quick google search presented a few other reasons: http://www.crazyforcode.com/cant-static-class-singleton/
    Whether or not any of these are problems for you is not a judgement I could make. I personally haven't had to consider any of these, even on professional projects.
     
    Last edited: Jan 10, 2020
    DoomDude99 likes this.
  6. APSchmidtOfOld

    APSchmidtOfOld

    Joined:
    Aug 8, 2016
    Posts:
    4,473
    Is a static class as "stable" as a singleton seems to be?
    If this is still accurate, then it's good to know. ;)

    But then, if I need those public static variables to be stored in memory forever and I need my script to be also there forever, is there a problem using both?
     
    DoomDude99 likes this.
  7. APSchmidtOfOld

    APSchmidtOfOld

    Joined:
    Aug 8, 2016
    Posts:
    4,473
  8. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Static classes should be more stable than singletons, particularly in Unity. A singelton's gameObject might get destroyed by accident, but a static class doesn't have that problem. Of course, if your singleton isn't a Component, then you probably don't need to worry about that.
    Looks pretty accurate to me; singletons don't really get rid of the issues of global state, since what difference does it make if you say
    GlobalClass.myInt
    everywhere or
    GlobalClass.Instance.myInt
    ? It's the same problem, now just more complicated.
     
    DoomDude99 and APSchmidtOfOld like this.
  9. DoomDude99

    DoomDude99

    Joined:
    May 11, 2019
    Posts:
    87
    Thanks for the replies @all . The coordinates that I'm planning on storing should always be in memory. As far as I know static fields are atomic (the coordinates are updated and read from different threads). What's the best way of implementing atomic read/writes on singleton fields?
     
  10. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,835
    In Unity, I think the main reason most people use singletons instead of static classes/variables is specifically because the singleton can be a MonoBehaviour, giving it access to coroutines, magic methods (Start, Update, etc.), and the inspector.

    It's theoretically possible to use singletons in ways that would help if you ever decided you needed more than one copy of that thing after all, but I don't think most Unity users actually use them in those ways.
     
  11. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    The way you have it now (just plain public static floats) is atomic and threadsafe. But my advice if you're a new programmer is to keep it simple; you don't need to worry about thread safety unless you're actually using threads. By default, everything runs on the main thread. All of Unity's standard code like Update() and Coroutines all run in the main thread, and GameObjects and their components generally can't be touched by separate threads anyway.
     
    DoomDude99 likes this.
  12. APSchmidtOfOld

    APSchmidtOfOld

    Joined:
    Aug 8, 2016
    Posts:
    4,473
    Hi,

    How bad or good is that? The script below must be kept between scenes and
    Code (CSharp):
    1.         SomeClass.SomeFunction();
    is accessed from another script.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SomeClass : MonoBehaviour
    4. {
    5.     public static bool someBool;
    6.  
    7.     private static SomeClass someClass;
    8.  
    9.     private void Awake()
    10.     {
    11.         if(someClass != null && someClass != this)
    12.         {
    13.             Destroy(gameObject);
    14.             return;
    15.         }
    16.  
    17.         someClass = this;
    18.  
    19.         DontDestroyOnLoad(gameObject);
    20.     }
    21.  
    22.     public static void SomeFunction()
    23.     {
    24.         someBool = true;
    25.     }
    26. }
     
  13. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    Yeah that looks fine. :)
     
    APSchmidtOfOld likes this.
  14. APSchmidtOfOld

    APSchmidtOfOld

    Joined:
    Aug 8, 2016
    Posts:
    4,473
    Ah, I feel better, thank you. :)
     
    DoomDude99 likes this.
  15. DoomDude99

    DoomDude99

    Joined:
    May 11, 2019
    Posts:
    87
  16. APSchmidtOfOld

    APSchmidtOfOld

    Joined:
    Aug 8, 2016
    Posts:
    4,473
    DoomDude99 likes this.