Search Unity

NullReferenceException on health pickup script [Fixed!!]

Discussion in 'Scripting' started by LadyAth, Nov 22, 2014.

  1. LadyAth

    LadyAth

    Joined:
    Jan 17, 2014
    Posts:
    158
    I'm battling to get my health pickup to work. I have a script for health and a script for health pickups, but I cannot get the pickup to add to my current health. I get the error message:

    NullReferenceException: Object reference not set to an instance of an object
    LHPickupHeal.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/Pickups/LHPickupHeal.cs:22)

    I've searched, but not had any luck in fixing the problem. If I take out the line in question, the object disappears as it should, but adds no health of course. Any advice on how to fix my pickup script so it works? I realise it might be easier to put the pickup in the health script, but I have a number of pickups of which health is just one, which is why I have split it out.



    Scripts below:

    HEALTH SCRIPT
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. public class LHPCHealth : MonoBehaviour
    6. {
    7.  
    8.         public int maxHealth = 100;            //PC max health
    9.         public int curHealth = 100;            //PC current health
    10.         bool isDead = false;                     //Bool if PC is dead
    11.         public Slider healthSlider;             // Reference to the UI's health bar.
    12.         LHPCMovement pcMovement;     // Reference to the player's movement.
    13.         LHPCAttack pcAttack;                // Reference to the LHPCAttack script.
    14.  
    15.         void Awake ()
    16.         {
    17.                 pcMovement = GetComponent<LHPCMovement> ();
    18.                 pcAttack = GetComponent<LHPCAttack> ();
    19.         }
    20.  
    21.         void Start ()
    22.         {
    23.                 curHealth = maxHealth;
    24.         }
    25.  
    26.         void Update ()
    27.         {
    28.                 healthSlider.value = curHealth;
    29.                 if (curHealth <= 0 && !isDead) {
    30.                         Death ();
    31.                 }
    32.         }
    33.    
    34.         public void AddHealth (int amount)
    35.         {
    36.                 curHealth += amount;
    37.                 if (curHealth <= 0) {
    38.                         curHealth = 0;
    39.                 }
    40.            
    41.                 if (curHealth >= maxHealth) {
    42.                         curHealth = maxHealth;
    43.                 }
    44.         }
    45.  
    46.         public void TakeDamage (int amount)
    47.         {
    48.                 curHealth -= amount;
    49.         }
    50.  
    51.         void Death ()
    52.         {
    53.                 isDead = true;              
    54.                 pcMovement.enabled = false;
    55.                 pcAttack.enabled = false;
    56.                 LHPCDead.show ();
    57.                 Application.LoadLevel ("TavernBedroom");
    58.         }
    59. }
    60.  

    PICKUP SCRIPT
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class LHPickupHeal : MonoBehaviour
    5. {
    6.         public AudioClip healGrab;                      // Audioclip to play when the heal is picked up
    7.         public int healPoints;                             //Amount to heal
    8.         LHPCHealth lhPCHealth;                      //Reference to PC health script
    9.         GameObject player;                              // Reference to the player.
    10.  
    11.        
    12.         void Awake ()
    13.         {
    14.                 player = GameObject.FindGameObjectWithTag ("Player");
    15.                 lhPCHealth = GetComponent<LHPCHealth> ();
    16.         }
    17.    
    18.         void OnTriggerEnter (Collider other)
    19.         {
    20.                 if (other.gameObject == player) {
    21.                         AudioSource.PlayClipAtPoint (healGrab, transform.position);
    22.                         lhPCHealth.AddHealth (healPoints);           / <----------error here!
    23.                         Destroy (gameObject);
    24.                 }
    25.         }
    26. }
     
  2. RSG

    RSG

    Joined:
    Feb 20, 2013
    Posts:
    93
    I looks like lhPCHealth is not attached to your game object, so your provably getting null when you call:

    Code (CSharp):
    1. lhPCHealth = GetComponent<LHPCHealth> ();
     
  3. LadyAth

    LadyAth

    Joined:
    Jan 17, 2014
    Posts:
    158
    LHPCHealth is definitely attached to the player character and on line 22 of the pickup script, intellisense picks up the AddHealth function without a problem. All seems good when creating the script, but when in game mode...not so much. Is there another way to force it to get the health script from the player instance apart from setting the references for both player and lhPCHealth in Awake? Or should I use Start instead? Sorry, brain has gone all moggy in trying to find the problem :(
     
  4. RSG

    RSG

    Joined:
    Feb 20, 2013
    Posts:
    93
    Intellisense is a tool that provides you with options when you write code; it does not tell you whether a reference is null.

    The error that you got occurs when you try to use an object that has not been defined. Your script could be there but lhPCHealth is not pointing to it. Maybe Unity is calling OnTriggerEnter before Awake. Instead of using Awake try using OnEnable, this function gets called when the objects is loaded.

    You could also create a property that updates its reference if the reference is null:

    Code (CSharp):
    1. private LHPCHealth lhPCHealth
    2. {
    3.     get{ return _lhPCHealth??(_lhPCHealth = GetComponent<LHPCHealth>()); }
    4. }
    5. private LHPCHealth _lhPCHealth
    This property will only return null if unity cannot find LHPCHealth when calling GetComponent.
     
  5. Stoven

    Stoven

    Joined:
    Jul 28, 2014
    Posts:
    171
    From the looks of your scripts, LHPCHealth is located on the player character GameObject and LHPickupHeal is on a different GameObject that the character can interact with.

    The version of GetComponent that you're using wont work because you're trying to get the player's health from the pickup GameObject as opposed to the player.

    You probably meant to do something like this:

    Code (CSharp):
    1.                 player = GameObject.FindGameObjectWithTag ("Player");
    2.                 lhPCHealth = player.GetComponent<LHPCHealth> ();

    This way, you're explicitly stating what GameObject you want to get the component from.
     
  6. LadyAth

    LadyAth

    Joined:
    Jan 17, 2014
    Posts:
    158
    @RSG: I am beginning to think that I will have to restructure my approach on my health script. You are right and it does not find LHPCHealth and the function (Addhealth) to execute the trigger event of adding health. I set a public bool on LHPCHealth and changed the health pickup script to just change the bool. It fails with the same error. What is odd is that my keypickup script (structured the same way) has no such issues. Will play around a bit more, but in the meantime, if you see anything wrong with LHPCHealth, please let me know. And thank you for the assistance so far! I am sure it is something silly, but I am just not seeing the source of the problem - but at least now understand that it seems to lie with my health script and not the health pickup!


    @Stoven: Interesting! Will try quick before I start tearing up my health script. You are correct that LHPCHealth is on my player char and LHPickupHeal is on the healing prefab.
     
  7. LadyAth

    LadyAth

    Joined:
    Jan 17, 2014
    Posts:
    158
    OMW!!! Stoven! You found my problem :)
    Thank you both for helping me on the right track to fix this problem. VERY much appreciated!
     
  8. Stoven

    Stoven

    Joined:
    Jul 28, 2014
    Posts:
    171
    ...What does OMW mean? I think I know, but...
     
  9. LadyAth

    LadyAth

    Joined:
    Jan 17, 2014
    Posts:
    158
    Oh my word :)