Error updating UI text when instantiated object is destroyed

Hello all,

I’m new to Unity and scripting in C# and I have encountered a problem.

Desierd behaviour.
At the start of the game, asteroids are instantiated by s_GameManager.cs.
When the player shoots an asteroid the s_asteroid.cs sends an int-value (points) to the s_ScoreDisplay.cs.
s_ScoreDisplay.cs should update the Score.text, currently a child gameobject to the UI (Canvas).

Error
When an asteroid is destroyed, an error is encountered at line 19, where the s_Asteroid.cs sends points to the s_Scoredisplay.cs.

Unity Console error:
NullReferenceException: Object reference not set to an instance of an object
s_Asteroid.OnTriggerEnter2D (UnityEngine.Collider2D collider) (at Assets/Scripts/s_Asteroid.cs:19)

Scripts:
s_GameManager.cs

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

public class s_GameManager : MonoBehaviour {

    public GameObject Asteroid;

    // Use this for initialization
    private void Start()
    {
        for (int i = 0; i <= 10; i++) //number of asteroids to be instansiated at beggining of level
        {
            Vector3 randomPosistion = new Vector3(Random.Range(-20f, 20f), Random.Range(-10f, 10f), -1f); //Random position for asteroid to spawn on
            Instantiate(Asteroid, randomPosistion, Quaternion.identity); //Create asteroid at random position
        }
    }

    // Update is called once per frame
    void Update () {
      
    }
}

s_Asteroid.cs

using UnityEngine;

public class s_Asteroid : MonoBehaviour
{
    private float Health = 15f;
    private s_ScoreDisplay scoreDisplay;
    private int points = 10;

    public void OnTriggerEnter2D(Collider2D collider)
    {
        if (collider.gameObject.tag == "Projectile") //IF the collision is triggerd by plasma shot
        {
            Destroy(collider.gameObject); //Destroy plasma shot
            Health--;
            if (Health <= 0f) //If asteroids health is below or equal to 0
            {
                Destroy(gameObject); //Destroys asteroid
                Debug.Log("Sending points...");
                scoreDisplay.ScoreCounter(points); //Send points to ScoreDisplay
                Debug.Log("Points sent");
            }
        }
    }
}

s_ScoreDisplay.cs

using UnityEngine;
using UnityEngine.UI;

public class s_ScoreDisplay : MonoBehaviour
{
    private Text scoreText; //Score text
    private int score;

    // Use this for initialization
    public void Start()
    {

        scoreText = GetComponent<Text>();
        score = 0;
        scoreText.text = score.ToString();
    }

    public void ScoreCounter(int points)
    {
        Debug.Log("Entering ScoreCounter()");
        score += points; //Increase score by the recived points from other functions
        Debug.Log("Before error ");
        scoreText.text = score.ToString();
        Debug.Log("End of scoreCounter");
    }
}

I’ve left my debug.log messages and comments so you easier get the idea of my problem.
I tried the forums for a solution and my best bet would be that there is some problem with that the instantiated asteroid can not “find” (reference?) the s_ScoreDisplay.cs.
But I’m at a loss.

Appreciate any help with the error!

Warm regards
Jonathan

First you could just send the score and then destroy the asteroid, but your problem is different for the error.

You never assign a value to

private s_ScoreDisplay scoreDisplay;

scoreDisplay has no value, so you get a null error. Either make scoreDisplay a singleton, or create the reference in a gamemanager type script which you could also access through the gamemanager (which would be a singleton)

Hi, thank you for your answer.

The reason I declare the private is so that I can call the method in s_ScoreDisplay (ScoreCounter())… Still I will look into your comment and see if I misunderstood it!

Thank you!

Jonathan

I don’t see anything in the code that actually assigns scoreDisplay to anything. Its default value is null. So you’ll get a null reference exception when trying to access it.

It has nothing to do with whether it’s private or public.

As @BlackPete added. It doesn’t care if it’s private, but you still have to assign a value to the variable. I just tried to give you an option since you may be instantiating your asteroids. If you are using object pooling on your asteroids, you can do something a bit different.

Thank you. Now I understand what you both mean. I Debug.Log(scoreDisplay), and I do get a null value. I will look in to it and get will ask more questions if I get lost! Thanks