Search Unity

NullReferenceException: Object reference not set to an instance of an object

Discussion in 'Scripting' started by imtreisis, Jan 12, 2022.

  1. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    I don't understand what happened, before i closed and saved it was working fine but now for some reason it says "NullReferenceException: Object reference not set to an instance of an object" even though i called it with the get component feature. The problem is they think im not calling the "statsScript" when i use "statsScript = GetComponent<Stats>();" it works but i want to get a tag not just call the whole thing.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class EnemyHealth : MonoBehaviour
    7. {
    8.     public Slider enemySlider3D;
    9.  
    10.     Stats statsScript;
    11.  
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.  
    16.         statsScript = GameObject.FindGameObjectWithTag("Enemy").GetComponent<Stats>();
    17.      
    18.  
    19.         enemySlider3D.maxValue = statsScript.maxHealth;
    20.         statsScript.health = statsScript.maxHealth;
    21.  
    22.     }
    23.  
    24.     // Update is called once per frame
    25.     void Update()
    26.     {
    27.         enemySlider3D.value = statsScript.health;
    28.      
    29.  
    30.     }
    31. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    No matter how mysterious this seems, the answer is always the same... ALWAYS. It is the single most common error ever.

    AFTER you fix it, then you can reason about why it happened.

    Don't waste your life spinning around and round on this error. Instead, learn how to fix it fast... it's EASY!!

    Some notes on how to fix a NullReferenceException error in Unity3D
    - also known as: Unassigned Reference Exception
    - also known as: Missing Reference Exception
    - also known as: Object reference not set to an instance of an object

    http://plbm.com/?p=221

    The basic steps outlined above are:
    - Identify what is null
    - Identify why it is null
    - Fix that.

    Expect to see this error a LOT. It's easily the most common thing to do when working. Learn how to fix it rapidly. It's easy. See the above link for more tips.

    You need to figure out HOW that variable is supposed to get its initial value. There are many ways in Unity. In order of likelihood, it might be ONE of the following:

    - drag it in using the inspector
    - code inside this script initializes it
    - some OTHER external code initializes it
    - ? something else?

    This is the kind of mindset and thinking process you need to bring to this problem:

    https://forum.unity.com/threads/why-do-my-music-ignore-the-sliders.993849/#post-6453695

    Step by step, break it down, find the problem.

    Here is a clean analogy of the actual underlying problem of a null reference exception:

    https://forum.unity.com/threads/nul...n-instance-of-an-object.1108865/#post-7137032
     
  3. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    It works when i use "statsScript = GetComponent<Stats>();" but i dont want the whole i want a objects tagged with "enemy" hence i used "statsScript = GameObject.FindGameObjectWithTag("Enemy").GetComponent<Stats>();" but it wont work
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    If you have more than one or two dots (.) in a single statement, you're just being mean to yourself.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.
     
  5. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    I will but do you know why it dosent work with the tag?
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    No, I can't read minds, and I can't read your computer.

    But you will know once you break it up and find which part is failing.
     
  7. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    playerObject.GetComponent returned null is what i got getting the tag was fine.
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    Then find out why there is no
    Stats
    Component on there!
     
  9. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    But the object has the stats script and is assigned the tag enemy. I think its a bug or something.
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    What if you had another GameObject tagged "Enemy" that doesn't have a Stats?
     
  11. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    Just went through everything but all objects tagged "enemy" has the script "Stats"
     
  12. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    Do you understand that if there are more than ONE GameObject marked "Enemy" it is not defined which one you get??

    Why would an enemy health bar be randomly connected to a random enemy's stats??

    To me it seems like each healthbar should be connected to the stats ON the given enemy, hence just a plain old GetComponent<Stats>() on the current enemy would be correct.

    What exactly are you doing here?
     
  13. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    But if i use GetComponent<Stats>() it will call the objects that have the Stat script including the player thats why i want only objects tagged enemy and their health . Also in my Stat script i have the get component tagged enemy health if it it goes below 0 they die but my player also dies, even though he is tagged player. But why would GetComponent<Stats>() tagged enemy not work and it gives me error.
    Code (CSharp):
    1. void Start()
    2.     {
    3.         heroCombatScript = GameObject.FindGameObjectWithTag("Player").GetComponent<HeroCombat>();
    4.         player = GameObject.FindGameObjectWithTag("Player");
    5.  
    6.         enemystats = GameObject.FindGameObjectWithTag("Enemy").GetComponent<Stats>();
    7.        
    8.  
    9.  
    10.  
    11.  
    12.  
    13.  
    14.  
    15.  
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update()
    20.     {
    21.         if (enemystats.health <= 0)
    22.         {
    23.             Destroy(gameObject);
    24.             heroCombatScript.targetedEnemy = null;
    25.             heroCombatScript.performMeleeAttack = false;
    26.            
    27.             CS.MinionKills += 1;
    28.             Gold.GoldCount += 20;
    29.  
    30.  
    31.             player.GetComponent<LevelUpStats>().SetExperience(expValue);
    32.         }
    33.  
    34.     }
     
    Last edited: Jan 13, 2022
  14. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    This is your problem. You are under a false impression of how GetComponent<T>() works.

    GetComponent<T>() will get the given component ONLY on the given GameObject where the calling script is located.

    It only gets ONE.

    Here are the docs:

    https://docs.unity3d.com/ScriptReference/GameObject.GetComponent.html

    It will only get ONE Stats object, the one ON THIS GameObject, if it exists.

    If you don't want it to happen on the player, do not put EnemyHealth script on the player.
     
  15. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    But player dosent have enemyhealth script
     
  16. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    Also, is there a compelling reason you are even doing GetComponent<T>() in the first place??

    Why not just put an EnemyHealth on an enemy, put a Stats object on it, then make a public Stats field in there and drag itself onto itself for the Stats. That way nobody is looking anywhere else.

    This stuff is really best kept super-simple. Anytime you do Get or Find you are complicating stuff. Ideally you only do that if you expect relationships to be dynamic.
     
  17. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    Umm im not sure im quite new to this as it for my Computer science project. The enemyhealth script is on all the enemys. Could you help me fixing this bit here. I would like it to get the certain enemy gameobject and when its health is below 0 it destroys only that gameobject not all of them. Forgot to mention, i know i dont have to get enemy tagged stats component and i can type if(health <0).... this was fine but i didnt want the player to be destroyed when his health was below 0 as i have another script called respawn that needs his physical position and it being destroyed didnt work. So is there any way to only destroy game objects that have health below 0 that are enemys and not player.
    Code (CSharp):
    1.   void Start()
    2.     {
    3.         heroCombatScript = GameObject.FindGameObjectWithTag("Player").GetComponent<HeroCombat>();
    4.         player = GameObject.FindGameObjectWithTag("Player");
    5.  
    6.         enemystats =GameObject.FindGameObjectWithTag("Enemy").GetComponent<Stats>();
    7.      
    8.      
    9.      
    10.  
    11.  
    12.  
    13.  
    14.  
    15.  
    16.  
    17.  
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.         if (enemystats.health <= 0)
    24.         {
    25.             Destroy(gameObject);
    26.             heroCombatScript.targetedEnemy = null;
    27.             heroCombatScript.performMeleeAttack = false;
    28.          
    29.             CS.MinionKills += 1;
    30.             Gold.GoldCount += 20;
    31.  
    32.  
    33.             player.GetComponent<LevelUpStats>().SetExperience(expValue);
    34.         }
    35.  
    36.     }
     
    Last edited: Jan 14, 2022
  18. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,735
    Given that it's taken 16 posts just to get us to this point, I'm going to suggest you set this gently aside and go do some super-basic enemy health tutorials. I am simply not going to type it all here again for you because it's all waiting for you on Youtube.

    Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

    How to do tutorials properly, two (2) simple steps to success:

    Tutorials are a GREAT idea. Tutorials should be used this way:

    Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That's how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.

    Fortunately this is the easiest part to get right: Be a robot. Don't make any mistakes.
    BE PERFECT IN EVERYTHING YOU DO HERE!!


    If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

    Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

    Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

    Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there's an error, you will NEVER be the first guy to find it.

    Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!
     
  19. imtreisis

    imtreisis

    Joined:
    Nov 2, 2019
    Posts:
    38
    I got a dog. Thank you for the help though much appreciation hopefully I complete my game before due date which is not long. :)
     
    Kurt-Dekker likes this.