0

I have a TextObject in my script which is attached to my canvas, as seen in the screenshots. Whenevery i try to run it i get that error, I tried many things but can't seem to figure out why this error appears.

using System;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;


//TODO: Implement Death screen when health falls to 0 - respawn priority(high)
public class DeathScreen:MonoBehaviour
{

    public Text timeLived;
    public Button replay;
    public Button mainMenu;
    public Button retry;
    

    // ReSharper disable Unity.PerformanceAnalysis
    public void Setup(int timeLivedInSeconds)
    {
        //SceneManager.UnloadSceneAsync("scenes/main");
        SceneManager.LoadScene("Scenes/deathScene");
        timeLived.text = "Time Survived: " + timeLivedInSeconds;
        retry.onClick.AddListener(Retry);
        replay.onClick.AddListener(Replay);
        mainMenu.onClick.AddListener(MainMenu);
    }

    
    public void Replay()
    {
        //TODO: call Replay
    }

    public void Retry()
    {
        SceneManager.UnloadSceneAsync("scenes/death");
        SceneManager.LoadScene("scenes/main");
    }

    public void MainMenu()
    {
        SceneManager.UnloadSceneAsync("scenes/death");
        SceneManager.LoadScene("scenes/menu");
    }
}

enter image description here enter image description here

ERROR:

NullReferenceException: Object reference not set to an instance of an object
DeathScreen.Setup (System.Int32 timeLivedInSeconds) (at Assets/Scripts/Mechanics/DeathScreen.cs:23)
DeathScreen.Start () (at Assets/Scripts/Mechanics/DeathScreen.cs:16)
Matze._
  • 77
  • 11
  • You start your method with loading a different scene .. so most probably everything else is unloaded and thus all the button instances either don't exist anymore or not yet in the moment you try to access them. – derHugo Jan 29 '21 at 20:50
  • @derHugo i have a main class in which on death i load this, which should work – Matze._ Jan 29 '21 at 20:52
  • Your death screen instance and everything else is destroyed the moment you for some reason reload that same scene .. of course there will be a new one but the one you called that method on will be gone and along with it all referenced objects as well. I suggest you [Debug your Code with Breakpoints](https://docs.unity3d.com/Manual/ManagedCodeDebugging.html) – derHugo Jan 29 '21 at 20:54
  • Why do you think you have to call `SceneManager.LoadScene("Scenes/deathScene")` when you already are in the deathScene? – derHugo Jan 29 '21 at 20:55
  • I am not in the death scene, i am in my main, i die. then i switch to the deathScene – Matze._ Jan 29 '21 at 20:57
  • I load the scene, which should load all the variables instantiated in the scene, or is my thinking wrong here. In the debugger it showed all the variables – Matze._ Jan 29 '21 at 20:57
  • Note that also the `UnloadSceneAsync` is completely redundant as Unity anyway unloads everything when using `LoadScene` without using additive loading ;) – derHugo Jan 29 '21 at 20:57
  • Thats why it's commented out – Matze._ Jan 29 '21 at 20:58
  • Thought at first i needed it – Matze._ Jan 29 '21 at 20:58
  • So in which scene is the DeathScreen script? – derHugo Jan 29 '21 at 20:58
  • The procedure for the death scene is, i call the death script when my health is below 0, then the death scene is loaded, then it changes the time lived. – Matze._ Jan 29 '21 at 20:58
  • The deathScreen script is in the deathsceen – Matze._ Jan 29 '21 at 20:59
  • but as said its called from annother script – Matze._ Jan 29 '21 at 20:59
  • So as said before the moment you call the `Setup` method you already have to be inside the deathScene ... Then you load the same scene again which destroyed the currently executing instance along with it and also the referenced objects -> you get the exception at right the next line this this very same instance of `timeLived` will not exist anymore since its scene was unloaded and a new scene loaded (it is the same scene asset but a new instance of it) – derHugo Jan 29 '21 at 21:00
  • "load the same scene again" indeed not, as the death scene isn't loaded when the script is called – Matze._ Jan 29 '21 at 21:01
  • the death scene isnt loaded before so the variables get loaded when SceneManager.LoadScene("Scenes/deathScene"); is executed – Matze._ Jan 29 '21 at 21:01
  • If the deathScene isn't loaded then how do you call `Setup` .. a method belonging to `DeathScreen` which you just said is part of the deathScene .... ?? Either way this very instance and all referenced objects are destroyed the moment you call `LoadScene` .. that's all I can tell you .. and the debugger as well – derHugo Jan 29 '21 at 21:03
  • DeathScreen death = new DeathScreen(); death.Setup(timeLived.Minute); – Matze._ Jan 29 '21 at 21:04
  • Well, the debugger tells me something different indeed – Matze._ Jan 29 '21 at 21:05
  • Oooooo boy ... Please see my comment on one of the answers below ... You **never** use `new` for `MonoBehaviour` you actually should get a warning about it telling you exactly this ...maybe start to post a complete reproducible code .. e.g. you don't even add the `Start` method etc. A last time: The main issue is you using `new` on a `MonoBehaviour` and all your referenced objects being destroyed the moment you call `LoadScene` ^^ – derHugo Jan 29 '21 at 21:05
  • Yeah, i saw that comment, but thats how we did programm such a thing in java. And this is very logical. I declare a death scene and then call the setup, isn't it. – Matze._ Jan 29 '21 at 21:06
  • Nope .. not if it is a `MonoBehaviour` (or actually `Component`) .. they simply may not exist without being attached to a `GameObject` in the scene. This is Unity ;) Unfortunately they only throw a warning instead of an exception .. nobody knows why since it is simply not valid ^^ – derHugo Jan 29 '21 at 21:09
  • So, how would i call my deathscene then, instead of using DeathScreen death = new DeathScreen(); death.Setup(timeLived.Minute); i just do SceneManager.LoadScene("Scenes/deathScene"); – Matze._ Jan 29 '21 at 21:09
  • i indeed hate unity from this point on – Matze._ Jan 29 '21 at 21:10
  • Throwing no error now, but the timeSurvived didn't change :c – Matze._ Jan 29 '21 at 21:11
  • Well where does `timeLivedInSeconds` come from? It is probably stored in the scene which is newly loaded so the value was never set before ;) – derHugo Jan 29 '21 at 21:15
  • hmm, yeah that worked before with the new DeathScene(). I load the scene, how do i "übergeben/supply?" it a value. Sorry, my english is indeed not the "yellow from the egg" – Matze._ Jan 29 '21 at 21:16
  • if (Health<=0) { SceneManager.LoadScene("Scenes/deathScene"); } – Matze._ Jan 29 '21 at 21:17
  • @derHugo Can't really find a way other than the one with the new DeathScene() – Matze._ Jan 29 '21 at 21:32

0 Answers0