Search Unity

Bug Can anyone help me with events, missing reference exception is caused due to game manager. Why?

Discussion in 'Scripting' started by sahilsharma220202004, May 29, 2021.

  1. sahilsharma220202004

    sahilsharma220202004

    Joined:
    Nov 18, 2020
    Posts:
    33
    Code (CSharp):
    1. public class GameManager : MonoBehaviour
    2. {
    3.     [SerializeField] item[] items;
    4.     int luckyNum = 7;
    5.     int luckyItemNum;
    6.  
    7.     public TextMeshProUGUI playerLifeCountText;
    8.     private GameObject player;
    9.     private PlayerController playerControllerScript;
    10.  
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         player = GameObject.Find("Player");
    15.         playerControllerScript = player.GetComponent<PlayerController>();
    16.  
    17.         PlayerController.PlayerDeathHandler += PlayerController_PlayerDeathHandler;
    18.     }
    19.  
    20.     private void PlayerController_PlayerDeathHandler()
    21.     {
    22.         if (playerControllerScript.playerLifeCount >= 0)
    23.             StartCoroutine(SetPlayerActive());
    24.     }
    25.  
     
  2. sahilsharma220202004

    sahilsharma220202004

    Joined:
    Nov 18, 2020
    Posts:
    33
    Its from line 23 saying game manager is being destroyed and you are still trying to access it but I am not destroying game manager .
     
  3. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    When you add a listener you should always have a way to remove it when you are done. don't expect the event to clean it up for you. You added "PlayerController_PlayerDeathHandler" in start but did not clean it up on destroy. PlayerDeathHandler also looks like a static event/delegate so its also not cleaned up automatically if PlayerController is destroyed.

    The reason you are getting a missing reference exception is because:
    1. You first loaded the GameObject with the GameManager script.
    2. everything seems to run fine.
    3. you destroy the GameManager script, likely by unloading the scene it was in
    4. PlayerController_PlayerDeathHandler is NOT cleaned up
    5. you reload back into the scene later in the same play session. Loading a new GameManager instance and binding a new callback to PlayerController.PlayerDeathHandler.
    6. PlayerController.PlayerDeathHandler now has 2 handlers attached to it, not one, and one of them points to the 1st GameManager Instance as its delegate target which no longer exists.
    7.next time PlayerController.PlayerDeathHandler is invoked it will raise a Missing Reference exception because the monobehaviour one of the callbacks refers to was destroyed in a previous scene,

    The class data for the monobehaviour in Unity's C++ environment has already been unloaded but the reference in the C# environment could not be cleaned up by the GC because it sees that your event is still pointing to it. the C# proxy class still exists and since you are trying to use that class while its C++ data is unloaded Unity throws a missingReferenceException in response.

    As a rule, when a class adds a listener to an event, UnityEvent, or delegate, you should always make that class responsible for cleaning up that listener manually as well. By definition of the Observer pattern, the invoking class should not have to worry about the lifecycles or implementation to whatever code subscribes to its events. it should not have to worry about explicitly adding/removing specific listeners itself, that should be the responsibility of the listeners.

    Its for this reason I avoid adding lamdas as listeners to events. I mostly use explicit methods or cached delegates so that I can later removing them with little difficulty
     
    krzpia likes this.
  4. mataveli91

    mataveli91

    Joined:
    Oct 14, 2021
    Posts:
    1

    Cara literalmente você é um anjo enviado por Jejsus. Puta que pariu thanks very much.
     
    alberto5 likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689