Calling gameStatus.ResetGame() from SceneLoader causes Null Exception

I have been following along as best I can, attempting the challenges by pausing and trying to figure things out, so I am a little dissappointed I keep running into issues, when I think I am understanding… But, when I add the “gameStatus.ResetGame();” call to my SceneLoader script, it causes a Null Exception when I get to the final screen and click on “Retry.”
I have set a cached reference to the GameStatus class, and even dug into possible solutions in the community comments… but I have the same issue. If I remove the call from my LoadStartingScreen() method, everything works fine up to the point the score does not reset… as soon as I add the call to the other script, it breaks. I don’t under stand what is causing this.

public class GameStatus : MonoBehaviour
{

// Config Params
[Range(0.1f, 10f)] [SerializeField] float gameSpeed = 1.0f;
[SerializeField] int pointsPerBlock = 42;
[SerializeField] public TextMeshProUGUI scoreText;


// state variables
[SerializeField] public int currentScore = 0;


private void Awake()
{
    //singleton pattern
    int gameStatusCount = FindObjectsOfType<GameStatus>().Length;
    if (gameStatusCount > 1)
    {
        gameObject.SetActive(false);
        Destroy(gameObject);
    }
    else
    {
        DontDestroyOnLoad(gameObject);
    }
}

// Start is called before the first frame update
private void Start()
{
    scoreText.text = currentScore.ToString();
}

// Update is called once per frame
void Update()
{
    Time.timeScale = gameSpeed;
}

public void AddToScore()
{
    currentScore = currentScore + pointsPerBlock;
    //could be written as "currentScore += pointsPerBlock;"
    scoreText.text = currentScore.ToString();

}
public void ResetGame()
{
    Debug.Log(GetInstanceID() + "----ResetGame() was called.");
    gameObject.SetActive(false);
    Destroy(gameObject);
}

}

public class SceneLoader : MonoBehaviour
{
GameStatus gameStatus;

public void LoadNextLevel()
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    SceneManager.LoadScene(currentSceneIndex + 1);
}
public void LoadStartingScene()
{
    gameStatus.ResetGame(); //<-----causes Null Exception, remove and everything works but score doesnt reset...
    SceneManager.LoadScene(0);
}
public void LoadLevelSelect()
{
    SceneManager.LoadScene("2. Level Select");
}
public void LoadLevel1()
{
    SceneManager.LoadScene("Game Level 1");
}
public void LoadLevel2()
{
    SceneManager.LoadScene("Game Level 2");
}
public void LoadLevel3()
{
    SceneManager.LoadScene("Game Level 3");
}
public void LoadWinScreen()
{
    SceneManager.LoadScene("Win Screen");
}

public void QuitGame()
{
Application.Quit();
}
}

I got game to operate correctly, by using the code in the video “FindObjectOfType< GameStatus >().ResetGame();” and I think I understand what this is doing, but I dont understand why my earlier reference to GameStatus was not enough. Isn’t that what inputting the identifier GameStatus gameStatus is doing?

Hi Simon,

Good job on fixing the problem.

NullReferenceException means that a reference (“link”) to an instance is missing. It might be that the GameStatus object which was assigned to gameStatus, given it had been assigned at some point, was deleted during runtime. That’s impossible to tell just by looking at the code. Debug.Logs could have helped.

Thank you. I am still not quite 100% sure what I was missing, but I have run into this same issue, further in the tutorial as well, and I believe I have figured out what the issue is, but I am not 100% sure, so it leads me to this question… Can a Class reference ITSELF as a cached reference?
for Example, in the block break GameStatus Script what is the difference between the following —

public class GameStatus : MonoBehaviour
{

// Config Params
[Range(0.1f, 10f)] [SerializeField] float gameSpeed = 1.0f;
[SerializeField] int pointsPerBlock = 42;
[SerializeField] public TextMeshProUGUI scoreText;
[SerializeField] bool isAutoPlayEnabled;


// state variables
[SerializeField] public int currentScore = 0;


private void Awake()
{  
    //singleton pattern
    int gameStatusCount = FindObjectsOfType<GameStatus>().Length;
    if (gameStatusCount > 1)
    {
        gameObject.SetActive(false);
        Destroy(gameObject);
    }
    else
    {
        DontDestroyOnLoad(gameObject);
    }
}

and

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class GameStatus : MonoBehaviour
{

// Config Params
[Range(0.1f, 10f)] [SerializeField] float gameSpeed = 1.0f;
[SerializeField] int pointsPerBlock = 42;
[SerializeField] public TextMeshProUGUI scoreText;
[SerializeField] bool isAutoPlayEnabled;


// state variables
[SerializeField] public int currentScore = 0;

//cached ref
GameStatus gameStatus;


private void Awake()
{
    gameStatus = FindObjectsOfType<GameStatus>().Length;
    //singleton pattern
    int gameStatusCount = gameStatus.Length;
    if (gameStatusCount > 1)
    {
        gameObject.SetActive(false);
        Destroy(gameObject);
    }
    else
    {
        DontDestroyOnLoad(gameObject);
    }
}

cause this is the section that is giving me the error…

I believe by typing that all out, and relooking at the code, I have discovered my issue… when calling Awake(), It should be “int gameStatus =” not "gameStatus = "…

1 Like

You probably meant to write:

gameStatus = FindObjectsOfType<GameStatus>();
//singleton pattern
int gameStatusCount = gameStatus.Length;

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.