Search Unity

Need help debugging: cash cannot find manager in subsequent scenes.

Discussion in 'Scripting' started by Volcanicus, Aug 31, 2019.

  1. Volcanicus

    Volcanicus

    Joined:
    Jan 6, 2018
    Posts:
    169
    This is quite the pickle.
    So here is the observed behaviour:
    - Load scene 1: current cash = 100
    - Pick up cash: current cash = 115, UI updates accordingly, cash shop registers 115
    - Load scene 2 from scene 1: current cash = 115, this is reflected in the UI, the script and the cash shop
    - Pick up cash: current cash = 115, UI updates to 130, cash shop shows 115
    - Load scene 1 from scene 2: current cash = 115, this is reflected in the UI, the script and the cash shop
    - Pick up cash: current cash = 115, UI updates accordingly, cash shop registers 115

    Here is the desired behaviour:
    - Load scene 1: current cash = 100
    - Pick up cash: current cash = 115, UI updates accordingly, cash shop registers 115
    - Load scene 2 from scene 1: current cash = 115, this is reflected in the UI, the script and the cash shop
    - Pick up cash: current cash = 130, UI updates to 130, cash shop shows 130
    - Load scene 1 from scene 2: current cash = 130, this is reflected in the UI, the script and the cash shop
    - Pick up cash: current cash = 145, UI updates accordingly, cash shop registers 145

    When loading the second scene, the cash script I attached to my cash pickup does not find appropriately the protoMoneyManager however the first scene does and even when reloading it.
    upload_2019-8-30_23-19-35.png

    Is there a behaviour I am missing to point out that specific manager??

    Code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class Cash : MonoBehaviour
    7. {
    8.     public ProtoMoneyManager protoMoneyManager;
    9.     public float cashValue;
    10.     public string player = "Player";
    11.  
    12.     private void Start()
    13.     {
    14.         protoMoneyManager = FindObjectOfType<ProtoMoneyManager>();
    15.     }
    16.  
    17.     private void OnTriggerEnter(Collider other)
    18.     {
    19.         if (other.CompareTag(player))
    20.         {
    21.             if (protoMoneyManager.GetCurrentMoney() + cashValue > 9999)
    22.             {
    23.                 Debug.Log("Too much money.");
    24.                 return;
    25.             }
    26.             if (protoMoneyManager.GetCurrentMoney() + cashValue <= 9999)
    27.             {
    28.                 protoMoneyManager.AddMoney(cashValue);
    29.                 //DestroyCash();
    30.             }
    31.         }
    32.     }
    33.  
    34.     public void DestroyCash()
    35.     {
    36.         Destroy(gameObject);
    37.     }
    38. }
     
    Last edited: Aug 31, 2019
  2. CurtisMcGill

    CurtisMcGill

    Joined:
    Aug 7, 2012
    Posts:
    67
    From looking at your code it appears you are deleting the money manager and you would want to destroy the parent.

    I moved the value check to the money manager, fixed bug if you have 9995 coins and pick up 15 will go over 9999.

    I added do not destroy on load so there is one money manager that is persistence between loads.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Cash : MonoBehaviour
    4. {
    5.     public ProtoMoneyManager protoMoneyManager;
    6.     public float cashValue = 15;
    7.     public string player = "Player";
    8.  
    9.     private void Awake()
    10.     {
    11.         protoMoneyManager = FindObjectOfType<ProtoMoneyManager>();
    12.     }
    13.  
    14.     private void OnTriggerEnter(Collider other)
    15.     {
    16.         if (other.CompareTag(player))
    17.         {
    18.             protoMoneyManager.AddMoney(cashValue);
    19.             Destroy(this.gameObject);
    20.         }
    21.     }
    22. }
    This is my attempt at creating the ProtoMoneyManager that I used to test the script.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ProtoMoneyManager : MonoBehaviour
    4. {
    5.     public float money;
    6.  
    7.     void Start()
    8.     {
    9.         DontDestroyOnLoad(gameObject);
    10.         money = 100;
    11.     }
    12.  
    13.     public float GetCurrentMoney()
    14.     {
    15.         return money;
    16.     }
    17.  
    18.     public void AddMoney(float cashValue)
    19.     {
    20.         if (GetCurrentMoney() + cashValue <= 9999 - cashValue)
    21.             money += cashValue;
    22.     }
    23. }
     
    Ryiah likes this.
  3. Volcanicus

    Volcanicus

    Joined:
    Jan 6, 2018
    Posts:
    169
    I'd forgotten to add the money manager script. It's a bit different from yours but nonetheless:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class ProtoMoneyManager : MonoBehaviour
    7. {
    8.     public static ProtoMoneyManager protoMoneyManager = null; //to keep in memory between scenes
    9.     [SerializeField] private float money;
    10.     public Text moneyText; //set a text field from UI
    11.     public Text moneyTextShop;
    12.  
    13.     private void Awake()
    14.     {
    15.         if (protoMoneyManager == null)
    16.         {
    17.             protoMoneyManager = this;
    18.         }
    19.         else if (protoMoneyManager != this)
    20.         {
    21.             Destroy(gameObject);
    22.         }
    23.         //Dont destroy on reloading the scene
    24.         DontDestroyOnLoad(gameObject);
    25.     }
    26.  
    27.     void Start()
    28.     {
    29.         UpdateUI();
    30.     }
    31.  
    32.     public void AddMoney(float amount)
    33.     {
    34.         money += amount;
    35.         UpdateUI();
    36.     }
    37.  
    38.     public void SpendMoney(float amount)
    39.     {
    40.         money -= amount;
    41.         UpdateUI();
    42.     }
    43.  
    44.     public bool RequestMoney(float amount)
    45.     {
    46.         if (amount <= money)
    47.         {
    48.             return true;
    49.         }
    50.         return false;
    51.     }
    52.  
    53.     public void UpdateUI()
    54.     {
    55.         moneyText.text = money.ToString("N2") +" $";
    56.         moneyTextShop.text = money.ToString("N2") +" $";
    57.     }
    58.  
    59.     public float GetCurrentMoney()
    60.     {
    61.         return money;
    62.     }
    63.  
    64.     public void SetCurrentMoney(float savedMoney)
    65.     {
    66.         money = savedMoney;
    67.         UpdateUI();
    68.     }
    69. }
    70.  
    I am not deleting the manager when the scene loads nor do I want to delete any parent.
    Each scene contains its own manager for the cash but only 1 instance exists.

    Funny enough, I use the same logic for my game timer and there is no problem.
    The result is the same if the Cash script uses start/awake to find the protoMoneyManager; however, update allows it to find it. So I am guessing there is a timing issue somewhere...
     
  4. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    1. public Text moneyText; //set a text field from UI
    2. public Text moneyTextShop;


      Where do you get new references for these once you transition into the new scene? When you enter level 2 from level 1, these references will not work anymore, you need to reference them again.
     
  5. CurtisMcGill

    CurtisMcGill

    Joined:
    Aug 7, 2012
    Posts:
    67
    If each scene has its own manager and each time you load a level the money will go back to 100 unless you save the value before loading a scene then restore it after loaded.

    My files fix this problem by having 1 manager that is persistent between levels. When the player walks over the coin model it will put 15 in the manager and the coin will disappear.

    If I drag the player from the scene the coins will disappear and the manager goes up in value.

    This may not be what you are looking for but you should be able to combine them to get what you want.





     
    Last edited: Sep 1, 2019
    Ryiah likes this.