Object reference not set to an instance of an Object C#

Hi everyone,

I am new to unity and C# programming. I am making a game in which I’ve made a gameobject “Active Avatar”. I am adding some of the properties on this gameobject through a C# script attached to it.
This script is -

using UnityEngine;
using System.Collections;

public class AddChosenAvatarProperties : MonoBehaviour {

    //public Ball ball;
    // Use this for initialization
    //public GameObject healthsc;
    void Start () {
        string selectedAvatar = PlayerPrefs.GetString("SelectedAvatar");
        switch (selectedAvatar)
        {
            case "RollerBall":
                RollerBall();
                break;
            case "FireBall":
                break;
        }
    }
   
    void RollerBall()
    {
        // gameScript = ball.AddComponent<Ball>();
        Health healthsc = gameObject.AddComponent<Health>();
        healthsc.healthPoints = 1;
        healthsc.respawnHealthPoints = 1;
        healthsc.numberOfLives = 1;
        healthsc.isAlive = true;
        //healthsc.explosionPrefab = ;
        healthsc.healthPoints = 1;
        healthsc.LevelToLoad = "Level 1";

        Damage damagesc = gameObject.AddComponent<Damage>();
        damagesc.damageOnCollision = true;
        damagesc.damageAmount = 10;

    }
}

When I run the game I get an error -
NullReferenceException: Object reference not set to an instance of an object
GameManager.Update () (at Assets/Scripts/GameManager.cs:59)

My GameManager script is -

using UnityEngine;
using System.Collections;
using UnityEngine.UI;


public class GameManager : MonoBehaviour {

    public static GameManager gm;

    [Tooltip("If not set, the player will default to the gameObject tagged as Player.")]
    public GameObject player;

    public enum gameStates {Playing, Death, GameOver, BeatLevel};
    public gameStates gameState = gameStates.Playing;

    public int score=0;
    public bool canBeatLevel = false;
    public int beatLevelScore=0;

    public GameObject mainCanvas;
    public Text mainScoreDisplay;
    public GameObject gameOverCanvas;
    public Text gameOverScoreDisplay;

    [Tooltip("Only need to set if canBeatLevel is set to true.")]
    public GameObject beatLevelCanvas;

    public AudioSource backgroundMusic;
    public AudioClip gameOverSFX;

    [Tooltip("Only need to set if canBeatLevel is set to true.")]
    public AudioClip beatLevelSFX;

    private Health playerHealth;

    void Start () {
        if (gm == null)
            gm = gameObject.GetComponent<GameManager>();

        if (player == null) {
            player = GameObject.FindWithTag("Player");
        }

        playerHealth = player.GetComponent<Health>();

        // setup score display
        Collect (0);

        // make other UI inactive
        gameOverCanvas.SetActive (false);
        if (canBeatLevel)
            beatLevelCanvas.SetActive (false);
    }

    void Update () {
        switch (gameState)
        {
            case gameStates.Playing:
                if (playerHealth.isAlive == false)
                {
                    // update gameState
                    gameState = gameStates.Death;

                    // set the end game score
                    gameOverScoreDisplay.text = mainScoreDisplay.text;

                    // switch which GUI is showing       
                    mainCanvas.SetActive (false);
                    gameOverCanvas.SetActive (true);
                } else if (canBeatLevel && score>=beatLevelScore) {
                    // update gameState
                    gameState = gameStates.BeatLevel;

                    // hide the player so game doesn't continue playing
                    player.SetActive(false);

                    // switch which GUI is showing           
                    mainCanvas.SetActive (false);
                    beatLevelCanvas.SetActive (true);
                }
                break;
            case gameStates.Death:
                backgroundMusic.volume -= 0.01f;
                if (backgroundMusic.volume<=0.0f) {
                    AudioSource.PlayClipAtPoint (gameOverSFX,gameObject.transform.position);

                    gameState = gameStates.GameOver;
                }
                break;
            case gameStates.BeatLevel:
                backgroundMusic.volume -= 0.01f;
                if (backgroundMusic.volume<=0.0f) {
                    AudioSource.PlayClipAtPoint (beatLevelSFX,gameObject.transform.position);
                   
                    gameState = gameStates.GameOver;
                }
                break;
            case gameStates.GameOver:
                // nothing
                break;
        }

    }


    public void Collect(int amount) {
        score += amount;
        if (canBeatLevel) {
            mainScoreDisplay.text = score.ToString () + " of "+beatLevelScore.ToString ();
        } else {
            mainScoreDisplay.text = score.ToString ();
        }

    }
}

on line 59 as stated in the error I have playerHealth.isAlive == false , in my script I am adding isAlive boolean variable as healthsc.isAlive=true; still I am getting this error what can be the reason ? How to fix this ?

Welcome to the forum!

playerHealth is initialized in Start and then only used at line 59 where you have the problem. It seems that playerHealth itself is null, meaning that after the Start, it is not properly initialized, most likely because the player doesn’t have a Health component attached. You can easily test it e.g. by using Debug.Log after playerHealth was initialized. Just check whether it is null.

Yes you are right its a null value but I am attaching the Health component dynamically in my first script(line 24) then why it is not getting it ?

I am attaching the 1st script to the player where I’m attaching Health and Damage scripts dynamically and initializing the values.

It can happen that you Start in AddChosenAvatarProperties in executed first. Then everything should work as expected. However, if Start from GameManager is executed first, you query the Health, before it is actually added.
You need to make sure that AddChosenAvatarProperties’ Start is executed first. You may e.g. change it to Awake, since this is always executed first. Or you could modify the script execution order:

There are other options, like having an actual Player script, that has a direct reference to the health script, instead of having just a game object for the player.

Thank You so much Dantus. I changed void Start to Awake and its working fine now . Thanks a lot