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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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

Discussion in 'Scripting' started by shantanusingh994, Dec 28, 2015.

  1. shantanusingh994

    shantanusingh994

    Joined:
    Dec 26, 2015
    Posts:
    16
    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 -
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class AddChosenAvatarProperties : MonoBehaviour {
    5.  
    6.     //public Ball ball;
    7.     // Use this for initialization
    8.     //public GameObject healthsc;
    9.     void Start () {
    10.         string selectedAvatar = PlayerPrefs.GetString("SelectedAvatar");
    11.         switch (selectedAvatar)
    12.         {
    13.             case "RollerBall":
    14.                 RollerBall();
    15.                 break;
    16.             case "FireBall":
    17.                 break;
    18.         }
    19.     }
    20.    
    21.     void RollerBall()
    22.     {
    23.         // gameScript = ball.AddComponent<Ball>();
    24.         Health healthsc = gameObject.AddComponent<Health>();
    25.         healthsc.healthPoints = 1;
    26.         healthsc.respawnHealthPoints = 1;
    27.         healthsc.numberOfLives = 1;
    28.         healthsc.isAlive = true;
    29.         //healthsc.explosionPrefab = ;
    30.         healthsc.healthPoints = 1;
    31.         healthsc.LevelToLoad = "Level 1";
    32.  
    33.         Damage damagesc = gameObject.AddComponent<Damage>();
    34.         damagesc.damageOnCollision = true;
    35.         damagesc.damageAmount = 10;
    36.  
    37.     }
    38. }
    39.  
    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 -
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5.  
    6. public class GameManager : MonoBehaviour {
    7.  
    8.     public static GameManager gm;
    9.  
    10.     [Tooltip("If not set, the player will default to the gameObject tagged as Player.")]
    11.     public GameObject player;
    12.  
    13.     public enum gameStates {Playing, Death, GameOver, BeatLevel};
    14.     public gameStates gameState = gameStates.Playing;
    15.  
    16.     public int score=0;
    17.     public bool canBeatLevel = false;
    18.     public int beatLevelScore=0;
    19.  
    20.     public GameObject mainCanvas;
    21.     public Text mainScoreDisplay;
    22.     public GameObject gameOverCanvas;
    23.     public Text gameOverScoreDisplay;
    24.  
    25.     [Tooltip("Only need to set if canBeatLevel is set to true.")]
    26.     public GameObject beatLevelCanvas;
    27.  
    28.     public AudioSource backgroundMusic;
    29.     public AudioClip gameOverSFX;
    30.  
    31.     [Tooltip("Only need to set if canBeatLevel is set to true.")]
    32.     public AudioClip beatLevelSFX;
    33.  
    34.     private Health playerHealth;
    35.  
    36.     void Start () {
    37.         if (gm == null)
    38.             gm = gameObject.GetComponent<GameManager>();
    39.  
    40.         if (player == null) {
    41.             player = GameObject.FindWithTag("Player");
    42.         }
    43.  
    44.         playerHealth = player.GetComponent<Health>();
    45.  
    46.         // setup score display
    47.         Collect (0);
    48.  
    49.         // make other UI inactive
    50.         gameOverCanvas.SetActive (false);
    51.         if (canBeatLevel)
    52.             beatLevelCanvas.SetActive (false);
    53.     }
    54.  
    55.     void Update () {
    56.         switch (gameState)
    57.         {
    58.             case gameStates.Playing:
    59.                 if (playerHealth.isAlive == false)
    60.                 {
    61.                     // update gameState
    62.                     gameState = gameStates.Death;
    63.  
    64.                     // set the end game score
    65.                     gameOverScoreDisplay.text = mainScoreDisplay.text;
    66.  
    67.                     // switch which GUI is showing      
    68.                     mainCanvas.SetActive (false);
    69.                     gameOverCanvas.SetActive (true);
    70.                 } else if (canBeatLevel && score>=beatLevelScore) {
    71.                     // update gameState
    72.                     gameState = gameStates.BeatLevel;
    73.  
    74.                     // hide the player so game doesn't continue playing
    75.                     player.SetActive(false);
    76.  
    77.                     // switch which GUI is showing          
    78.                     mainCanvas.SetActive (false);
    79.                     beatLevelCanvas.SetActive (true);
    80.                 }
    81.                 break;
    82.             case gameStates.Death:
    83.                 backgroundMusic.volume -= 0.01f;
    84.                 if (backgroundMusic.volume<=0.0f) {
    85.                     AudioSource.PlayClipAtPoint (gameOverSFX,gameObject.transform.position);
    86.  
    87.                     gameState = gameStates.GameOver;
    88.                 }
    89.                 break;
    90.             case gameStates.BeatLevel:
    91.                 backgroundMusic.volume -= 0.01f;
    92.                 if (backgroundMusic.volume<=0.0f) {
    93.                     AudioSource.PlayClipAtPoint (beatLevelSFX,gameObject.transform.position);
    94.                    
    95.                     gameState = gameStates.GameOver;
    96.                 }
    97.                 break;
    98.             case gameStates.GameOver:
    99.                 // nothing
    100.                 break;
    101.         }
    102.  
    103.     }
    104.  
    105.  
    106.     public void Collect(int amount) {
    107.         score += amount;
    108.         if (canBeatLevel) {
    109.             mainScoreDisplay.text = score.ToString () + " of "+beatLevelScore.ToString ();
    110.         } else {
    111.             mainScoreDisplay.text = score.ToString ();
    112.         }
    113.  
    114.     }
    115. }
    116.  
    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 ?
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    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.
     
  3. shantanusingh994

    shantanusingh994

    Joined:
    Dec 26, 2015
    Posts:
    16
    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.
     
  4. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    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:
    http://docs.unity3d.com/Manual/class-ScriptExecution.html

    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.
     
  5. shantanusingh994

    shantanusingh994

    Joined:
    Dec 26, 2015
    Posts:
    16
    Thank You so much Dantus. I changed void Start to Awake and its working fine now . Thanks a lot