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

[SOLVED] Object Reference Not Set

Discussion in 'Scripting' started by jlpeyton, Feb 20, 2020.

  1. jlpeyton

    jlpeyton

    Joined:
    Dec 22, 2017
    Posts:
    57
    Why does this work:
    Code (CSharp):
    1. if (Input.GetMouseButtonDown(0))
    2.         {
    3.             InstantiateObject(position);
    4.         }

    But this doesn't:
    Code (CSharp):
    1. if (Input.GetMouseButtonDown(0))
    2.         {
    3.             if (hit.collider.gameObject.name == "Player_Brick" || hit.collider.gameObject.name == "Player_Ramp_Right")
    4.             {
    5.                 // Do something else eventually
    6.                 Debug.Log(hit.collider.gameObject.name);
    7.             }
    8.             else
    9.             {
    10.                 InstantiateObject(position);
    11.             }
    12.         }
    Error: Object reference not set to an instance of an object
     
  2. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Which line is it?

    Object reference not set to an instance of an object
    NullReferenceException indicates that you are trying to access member fields, or function types, on an object reference that points to null. That means the reference to an Object which is not initialized.

    In other words, something you're accessing doesn't exist.
     
  3. jlpeyton

    jlpeyton

    Joined:
    Dec 22, 2017
    Posts:
    57
    Line 15. This is the full class script

    Code (CSharp):
    1. public class SpawnerScript : MonoBehaviour
    2. {
    3.     public GameObject block;
    4.     public GameObject rampRight;
    5.  
    6.     // Update is called once per frame
    7.     void Update()
    8.     {
    9.         Vector2 position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    10.         Vector2 mousePos2D = new Vector2(position.x, position.y);
    11.         RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);
    12.  
    13.         if (Input.GetMouseButtonDown(0))
    14.         {
    15.             if (hit.collider.gameObject.name == "Player_Brick" || hit.collider.gameObject.name == "Player_Ramp_Right")
    16.             {
    17.                 // Do something else eventually
    18.                 Debug.Log(hit.collider.gameObject.name);
    19.             }
    20.             else
    21.             {
    22.                 InstantiateObject(position);
    23.             }
    24.         }
    25.     }
    26.  
    27.     private void InstantiateObject(Vector2 position)
    28.     {
    29.         position.x = Mathf.Round(position.x + .5f) - .5f;
    30.         position.y = Mathf.Round(position.y + .5f) - .5f;
    31.  
    32.         Instantiate(block, position, Quaternion.identity);
    33.     }
    34. }
     
  4. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    I guess you aren't checking if the "hit.collider" exists, something like:

    if (hit.collider != null && your code)
     
  5. jlpeyton

    jlpeyton

    Joined:
    Dec 22, 2017
    Posts:
    57
    When I GetMouseButtonDown and the gameObject name clicked on is "Player_Brick" or "Player_Ramp_Right" it will display in the console the object name without errors. If I click anywhere else it will not instantiate the object from the else statement and that's when the error appears.
     
  6. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    Yes, because if you hit an object, the "hit.collider.gameObject" exists, so it works. If you click where there is no object, you'r script (if (hit.collider.gameObject.name == "Player_Brick") looks for an object but there is none, so it gives an error, it's telling you "the hit.collider.gameObject" you're looking for it doesn't exist.

    https://docs.unity3d.com/ScriptReference/RaycastHit2D-collider.html

    Code (CSharp):
    1.  
    2. // Instead of
    3. if (hit.collider.gameObject.name == "Player_Brick" || hit.collider.gameObject.name == "Player_Ramp_Right"){}
    4.  
    5. // Try this
    6. if (hit != null && hit.collider != null && hit.collider.gameObject.name == "Player_Brick" || hit.collider.gameObject.name == "Player_Ramp_Right"){}
     
  7. jlpeyton

    jlpeyton

    Joined:
    Dec 22, 2017
    Posts:
    57
    But if an object doesn't exist where the player clicks would the else statement with the InstantiateObject() method not be called?
     
  8. Redden44

    Redden44

    Joined:
    Nov 15, 2014
    Posts:
    159
    If the object doesn't exist, the hit.collider is null and your code gives an error because you're trying to access something that does not exist, so the code will stop right there, it would not go to the else statement because of the error.

    If you add the check "hit.collider != null &&" and the object doesn't exists, it will skip the other checks and go directly to the else statement.
     
  9. jlpeyton

    jlpeyton

    Joined:
    Dec 22, 2017
    Posts:
    57
    Thank you for clarifying. I didn't understand why it was skipping but now it makes sense.