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. Dismiss Notice

Object References Lost On Level Reload

Discussion in 'Editor & General Support' started by Fariel, Oct 24, 2016.

  1. Fariel

    Fariel

    Joined:
    Feb 9, 2013
    Posts:
    29
    It appears that the Start function is not being called, or... something?

    I'm attempting to reload the current scene when the player dies. I'm doing that with the following:

    Code (CSharp):
    1.     public void Die() {
    2.         Invoke("Reload", 3f);
    3.     }
    4.  
    5.     void Reload() {
    6.         SceneManager.LoadScene(0,LoadSceneMode.Single);
    7.     }
    However, when the scene loads, a lot of my AI can't find references, and some user interface stuff is broken. For example:
    This error links to here:

    Code (CSharp):
    1.     void TurnTextBoxOn() {
    2.         voiceBox.gameObject.SetActive(true); //it links to this line in this function
    3.         StopCoroutine("DisplayText");
    4.         StartCoroutine("DisplayText");
    5.     }
    And voiceBox is set here, and only ever set here:

    Code (CSharp):
    1.     Transform voiceBox;
    2.     Text textBox;
    3.     Image speakerImage;
    4.     AudioSource textSound;
    5.     void Start () {
    6.         voiceBox = transform.FindChild("SpeechPanel");
    7.         textBox = voiceBox.FindChild("Text").GetComponent<Text>();
    8.         speakerImage = voiceBox.FindChild("Image").GetComponent<Image>();
    9.         voiceBox.gameObject.SetActive(false);
    10.     }
    This isn't the only place I have errors from things not being found when I reload the level, but this is the easiest one to reproduce because I have only to walk up to a station after respawning and I get the error.

    Can anyone tell me why this is happening? How to fix it? What even might be going on? I'm lost.

    Things I've tried:
    Loading a second scene and immediately switching back to the game.
    Loading a second scene and waiting a second before switching back to the game.
    Loading a second scene, calling unload on the first scene, then loading it again.
    That, but with waiting.
    That, but with Resources.UnloadUnusedAssets();
    That, but manually destroying EVERYTHING in the first scene before I switch.
    and a whole bunch of other random things.

    The only DontDestroyOnLoad object I have is Rewired, which is used for input and cannot be related to any of the errors I have.

    I do not use static variables.

    I'm an idiot.

    Please make sure you review your code when you open a project you haven't worked on a for a while.

    What had happened: I have a "game manager" that is used for global access to the UI menus so they don't have to reference eachother and I can do some other weird and otherwise lazy behaviour. I completely forgot it existed, since the UI menus themselves don't actually reference the game manager, they're just collections of functions for opening / closing / performing operations on menus.

    The game manager is a static class with a singleton pattern and, because of that, was not being recreated when the scene loaded. This meant that the references were to objects from the previous scene.

    If anyone is confused about how/why the singleton pattern, or game manager type thing, breaks on level loads, I can answer some questions. Just ask.
     
    Last edited: Oct 24, 2016
  2. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    958
    Well, the pattern doesn't really break on level loads, it just can be misused in ways that do. Singletons should generally be marked DontDestroyOnLoad and either not retain direct references to objects that are not or be prepared to follow the lifetime of those objects.

    This is especially important if you consider that it's rather easy to keep a C# reference to a dead object, keeping in alive from the GC's point of view, even though the native object is long gone.