0
\$\begingroup\$

I have a GameManager Singleton script, which a public property:

public bool IsDroneDeployed = false

When I set this value to true/false using a script... it seems these two versions of the value are different.

IsDroneDeployed = !IsDroneDeployed;
//GameManager.Instance.IsDroneDeployed

If I set the first one and log it out, the "instance" version isn't updated.

I would think when I'm in the GameManager, since it's a singleton I could just directly manipulate the variable, is that not the case?

Here's part of the code to show what I'm talking about...

public class GameManager : Singleton<GameManager>
{
    public bool IsDroneDeployed = false;
    
    public void LoadMapViewScene() //This is the action I kick off from an onClick event on a panel
    {
        Debug.Log($"=============Loading Map View");
        //LoadLevel(MapViewSceneName);
        SwitchDroneDeployedValue();
    }
        
    public void SwitchDroneDeployedValue()
    {
        Debug.Log($"============= Switching IsDroneDeployed Value BEFORE Switch: {IsDroneDeployed}");
        Debug.Log($"============= Switching GameManager.Instance.IsDroneDeployed value BEFORE Switch: {GameManager.Instance.IsDroneDeployed}");

        IsDroneDeployed = !IsDroneDeployed;
        //GameManager.Instance.IsDroneDeployed = !GameManager.Instance.IsDroneDeployed;
        Debug.Log($"============= Switching IsDroneDeployed value AFTER Switch: {IsDroneDeployed}");
        Debug.Log($"============= Switching GameManager.Instance.IsDroneDeployed value AFTER Switch: {GameManager.Instance.IsDroneDeployed}");
    }
    }

This results in this log..

============= Switching IsDroneDeployed Value BEFORE Switch: False
============= Switching GameManager.Instance.IsDroneDeployed value BEFORE Switch: False
============= Switching IsDroneDeployed value AFTER Switch: True
============= Switching GameManager.Instance.IsDroneDeployed value AFTER Switch: False

You can see that the "Instance" version doesn't get updated. Why is that? Only if I update GameManager.Instance.IsDroneDeployed directly

(GameManager.Instance.IsDroneDeployed = !GameManager.Instance.IsDroneDeployed;)  

it updates, but that seems wrong to me because the code is already in this class.

==== Adding the Singleton code as requested:

public class Singleton<T> : MonoBehaviour where T : Component
{
    //The instance is accessible only by the getter
    private static T _instance;
    
    public static bool IsInitialized => Instance != null; //Check if the instance exists already

    public static T Instance
    {
        get
        {
            if(_instance == null)
            {
                Debug.Log("Looking for existing instance of " + typeof(T).Name + " in memory to return");
                //Making sure there not other instances of same type in Memory
                _instance = FindObjectOfType<T>();

                if(_instance == null)
                {
                    Debug.Log("Instance not found.. creating instance of " + typeof(T).Name + " in memory");
                    GameObject obj = new GameObject();
                    obj.name = typeof(T).Name;
                    _instance = obj.AddComponent<T>();
                }

            }

            return _instance;
        }
    }

    public virtual void Awake()
    {
        if(_instance == null)
        {
            //If null, then this instance is now the singleton of the assigned type
            _instance = this as T;

            //making sure this instance is kept persisted across screens
            DontDestroyOnLoad(this.gameObject);
        }
        else
        {
            Debug.Log("Imposter of " + typeof(T).Name + " found. Destroying! pew pew pew.. boom!");
            //Destroy the imposter!
            Destroy(gameObject);
        }
    }

    protected virtual void OnDestroy()
    {
        if (_instance == this)
        {
            _instance = null;
        }
    }

}

This is the tree of: this.gameObject:

-       this.gameObject "GameManager (UnityEngine.GameObject)"  UnityEngine.GameObject
-       base    "GameManager (UnityEngine.GameObject)"  UnityEngine.Object
        hideFlags   None    UnityEngine.HideFlags
        name    "GameManager"   string
-       Static members      
-       Non-Public members      
        OffsetOfInstanceIDInCPlusPlusObject -1  int
        cloneDestroyedMessage   "Instantiate failed because the clone was destroyed during creation. This can happen if DestroyImmediate is called in MonoBehaviour.Awake." string
        objectIsNullMessage "The Object you want to instantiate is null."   string
-       Non-Public members      
        m_CachedPtr 0x1e770033870   System.IntPtr
        m_InstanceID    -1186   int
        m_UnityRuntimeErrorString   null    string
        activeInHierarchy   true    bool
        activeSelf  true    bool
        audio   System.NotSupportedException: audio property has been deprecated    UnityEngine.Component
        constantForce   System.NotSupportedException: constantForce property has been deprecated    UnityEngine.Component
+       gameObject  "GameManager (UnityEngine.GameObject)"  UnityEngine.GameObject
        isStatic    false   bool
        layer   0   int
        light   System.NotSupportedException: light property has been deprecated    UnityEngine.Component
        renderer    System.NotSupportedException: renderer property has been deprecated UnityEngine.Component
        rigidbody2D System.NotSupportedException: rigidbody2D property has been deprecated  UnityEngine.Component
-       scene   {UnityEngine.SceneManagement.Scene} UnityEngine.SceneManagement.Scene
        buildIndex  -1  int
        handle  -12 int
        isDirty false   bool
        isLoaded    true    bool
        isSubScene  false   bool
        name    "DontDestroyOnLoad" string
        path    "DontDestroyOnLoad" string
        rootCount   4   int
-       Non-Public members      
        dirtyID 0   int
        guid    "00000000000000000000000000000000"  string
        loadingState    Loaded  UnityEngine.SceneManagement.Scene.LoadingState
        m_Handle    -12 int
        tag "Untagged"  string
-       transform   "GameManager (UnityEngine.Transform)"   UnityEngine.Transform
+       base    "GameManager (UnityEngine.Transform)"   UnityEngine.Component
        childCount  0   int
+       eulerAngles "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       forward "(0.0, 0.0, 1.0)"   UnityEngine.Vector3
        hasChanged  true    bool
        hierarchyCapacity   1   int
        hierarchyCount  1   int
+       localEulerAngles    "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       localPosition   "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       localRotation   "(0.0, 0.0, 0.0, 1.0)"  UnityEngine.Quaternion
+       localScale  "(1.0, 1.0, 1.0)"   UnityEngine.Vector3
+       localToWorldMatrix  "1.00000\t0.00000\t0.00000\t0.00000\n0.00000\t1.00000\t0.00000\t0.00000\n0.00000\t0.00000\t1.00000\t0.00000\n0.00000\t0.00000\t0.00000\t1.00000\n"  UnityEngine.Matrix4x4
+       lossyScale  "(1.0, 1.0, 1.0)"   UnityEngine.Vector3
        parent  null    UnityEngine.Transform
+       position    "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       right   "(1.0, 0.0, 0.0)"   UnityEngine.Vector3
+       root    "GameManager (UnityEngine.Transform)"   UnityEngine.Transform
+       rotation    "(0.0, 0.0, 0.0, 1.0)"  UnityEngine.Quaternion
+       up  "(0.0, 1.0, 0.0)"   UnityEngine.Vector3
+       worldToLocalMatrix  "1.00000\t0.00000\t0.00000\t0.00000\n0.00000\t1.00000\t0.00000\t0.00000\n0.00000\t0.00000\t1.00000\t0.00000\n0.00000\t0.00000\t0.00000\t1.00000\n"  UnityEngine.Matrix4x4
+       Non-Public members      
-       Non-Public members      
        isStaticBatchable   false   bool

This is the tree of GameManager.Instance.gameObject

-       GameManager.Instance.gameObject "GameManager (UnityEngine.GameObject)"  UnityEngine.GameObject
-       base    "GameManager (UnityEngine.GameObject)"  UnityEngine.Object
        hideFlags   None    UnityEngine.HideFlags
        name    "GameManager"   string
-       Static members      
-       Non-Public members      
        OffsetOfInstanceIDInCPlusPlusObject -1  int
        cloneDestroyedMessage   "Instantiate failed because the clone was destroyed during creation. This can happen if DestroyImmediate is called in MonoBehaviour.Awake." string
        objectIsNullMessage "The Object you want to instantiate is null."   string
-       Non-Public members      
        m_CachedPtr 0x1e770033870   System.IntPtr
        m_InstanceID    -1186   int
        m_UnityRuntimeErrorString   null    string
        activeInHierarchy   true    bool
        activeSelf  true    bool
        audio   System.NotSupportedException: audio property has been deprecated    UnityEngine.Component
        constantForce   System.NotSupportedException: constantForce property has been deprecated    UnityEngine.Component
+       gameObject  "GameManager (UnityEngine.GameObject)"  UnityEngine.GameObject
        isStatic    false   bool
        layer   0   int
        light   System.NotSupportedException: light property has been deprecated    UnityEngine.Component
        renderer    System.NotSupportedException: renderer property has been deprecated UnityEngine.Component
        rigidbody2D System.NotSupportedException: rigidbody2D property has been deprecated  UnityEngine.Component
-       scene   {UnityEngine.SceneManagement.Scene} UnityEngine.SceneManagement.Scene
        buildIndex  -1  int
        handle  -12 int
        isDirty false   bool
        isLoaded    true    bool
        isSubScene  false   bool
        name    "DontDestroyOnLoad" string
        path    "DontDestroyOnLoad" string
        rootCount   4   int
-       Non-Public members      
        dirtyID 0   int
        guid    "00000000000000000000000000000000"  string
        loadingState    Loaded  UnityEngine.SceneManagement.Scene.LoadingState
        m_Handle    -12 int
        tag "Untagged"  string
-       transform   "GameManager (UnityEngine.Transform)"   UnityEngine.Transform
+       base    "GameManager (UnityEngine.Transform)"   UnityEngine.Component
        childCount  0   int
+       eulerAngles "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       forward "(0.0, 0.0, 1.0)"   UnityEngine.Vector3
        hasChanged  true    bool
        hierarchyCapacity   1   int
        hierarchyCount  1   int
+       localEulerAngles    "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       localPosition   "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       localRotation   "(0.0, 0.0, 0.0, 1.0)"  UnityEngine.Quaternion
+       localScale  "(1.0, 1.0, 1.0)"   UnityEngine.Vector3
+       localToWorldMatrix  "1.00000\t0.00000\t0.00000\t0.00000\n0.00000\t1.00000\t0.00000\t0.00000\n0.00000\t0.00000\t1.00000\t0.00000\n0.00000\t0.00000\t0.00000\t1.00000\n"  UnityEngine.Matrix4x4
+       lossyScale  "(1.0, 1.0, 1.0)"   UnityEngine.Vector3
        parent  null    UnityEngine.Transform
+       position    "(0.0, 0.0, 0.0)"   UnityEngine.Vector3
+       right   "(1.0, 0.0, 0.0)"   UnityEngine.Vector3
+       root    "GameManager (UnityEngine.Transform)"   UnityEngine.Transform
+       rotation    "(0.0, 0.0, 0.0, 1.0)"  UnityEngine.Quaternion
+       up  "(0.0, 1.0, 0.0)"   UnityEngine.Vector3
+       worldToLocalMatrix  "1.00000\t0.00000\t0.00000\t0.00000\n0.00000\t1.00000\t0.00000\t0.00000\n0.00000\t0.00000\t1.00000\t0.00000\n0.00000\t0.00000\t0.00000\t1.00000\n"  UnityEngine.Matrix4x4
+       Non-Public members      
-       Non-Public members      
        isStaticBatchable   false   bool
\$\endgroup\$
3
  • \$\begingroup\$ It looks like you have two copies of this script in existence. Try printing out the full hierarchy path of this.gameObject and GameManager.Instance.gameObject to find out which instance is stored as the global "current" instance, and which instance is currently executing your code. \$\endgroup\$ – DMGregory Jun 18 '20 at 13:58
  • \$\begingroup\$ It would be interesting to see how the class Singleton is implemented and used, because it's neither a class from the Unity scripting API nor from the C# standard library. My guess is that it is not actually a singleton and you are dealing with two different instances of it. \$\endgroup\$ – Philipp Jun 18 '20 at 14:13
  • \$\begingroup\$ Added the singleton code and the output of this.gameObject and GameManager.Instance.gameObject. Maybe I'm doing something wrong on the Singleto? \$\endgroup\$ – Mastro Jun 19 '20 at 3:52
1
\$\begingroup\$

You probably call your SwitchDroneDeployedValue() on a self created instance. With Unity's implementation of the singleton pattern you don't have to do this.

This should work for you. Replace your method call with this call:

GameManager.Instance.SwitchDroneDeployedValue();
\$\endgroup\$
2
  • \$\begingroup\$ You are right, that fixed it, but don't understand. Yes, it's self created but didn't realize it worked that way. there's only one instance of it, so thought calling a method on it's self would work fine. If I use a button and call the method it works too but not if I call it from within another method on the same class. \$\endgroup\$ – Mastro Jun 19 '20 at 3:45
  • \$\begingroup\$ You can look up the source code here: wiki.unity3d.com/index.php/Singleton. Maybe it helps understanding. \$\endgroup\$ – Deep Thought Jun 19 '20 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.