2D raycast gives me an NullReferenceException

Hey ! :slight_smile:

Can anyone help me out with this issue below ? It’s a 2D game

 RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.up, 3.0f);

        Debug.DrawRay (transform.position, transform.up, Color.green);

 

        if(hit == null)

        {

            Debug.Log ("OmgZ the world is going down!");

        }

 

        if(hit != null)

        {

            string tag = hit.transform.tag;

            Debug.Log (tag);

            if(hit.collider.gameObject.tag == "Border")

            {

                Debug.Log ("Border hit!");

            }

        }

Here’s my error:

NullReferenceException: Object reference not set to an instance of an object
PCMovementScript.CheckRaycast () (at Assets/Scripts/PCMovementScript.cs:8
PCMovementScript.Update () (at Assets/Scripts/PCMovementScript.cs:17)

Can’t find the issue in my code, so does anyone have a clue ?
Thanks !

  • Andreas

Post the whole PCMovementScript and make sure the line numbering matches the one in your script, such that we can use that information.

Here’s the whole script:

using UnityEngine;
using System.Collections;

public class PCMovementScript : MonoBehaviour
{


	// Use this for initialization
	void Start ()
	{
	
	}
	
	// Update is called once per frame
	void Update ()
	{
		CheckRaycast ();

		if(Input.GetKey (KeyCode.W))
		{
			Debug.Log ("W Pressed !");
			transform.position = new Vector2(transform.position.x, transform.position.y + 0.1f);
			//transform.Rotate(0, 0, 0);
		}

		if(Input.GetKey (KeyCode.A))
		{
			Debug.Log ("A Pressed !");
			transform.position = new Vector2(transform.position.x - 0.1f, transform.position.y);
			/*if(transform.eulerAngles == new Vector3(0, 0, 0)  transform.eulerAngles == new Vector3(0, 0, 180)  transform.eulerAngles == new Vector3(0, 0, -90))
			{
				transform.Rotate(0, 0, 90);
			}*/
		}

		if(Input.GetKey (KeyCode.S))
		{
			Debug.Log ("S Pressed !");
			transform.position = new Vector2(transform.position.x, transform.position.y - 0.1f);
			/*if(transform.eulerAngles == new Vector3(0, 0, 0)  transform.eulerAngles == new Vector3(0, 0, 180)  transform.eulerAngles == new Vector3(0, 0, -90))
			{
				transform.Rotate(0, 0, 180);
			}*/
		}

		if(Input.GetKey (KeyCode.D))
		{
			Debug.Log ("D Pressed !");
			transform.position = new Vector2(transform.position.x  + 0.1f, transform.position.y);
			/*if(transform.eulerAngles == new Vector3(0, 0, 0)  transform.eulerAngles == new Vector3(0, 0, 180)  transform.eulerAngles == new Vector3(0, 0, -90))
			{
				transform.Rotate(0, 0, -90);
			}*/
		}

		/*InputListen();
		transform.rotation = Quaternion.Lerp (transform.rotation,  Quaternion.LookRotation(transform.position - prevLoc), Time.fixedDeltaTime * lookSpeed);*/
	}

	private void CheckRaycast()
	{
		/*for(int i = 0; i < 3; i++)
		{
			Debug.Log ("Rays initalized");
			Ray2D ray = new Ray2D(transform.position, transform.up);
			Debug.DrawRay (ray.origin, ray.direction);
			RaycastHit2D hit = new RaycastHit2D();
			
			if(Physics2D.Raycast(ray, out hit, 3.0f))	//(ray, hit, 3.0f))
			{
				if ( hit.transform.tag == "Border" ) 
				{
					Debug.Log ("Mob colliding to the border!");
				}
			}
		}*/

		RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.up, 3.0f);
		Debug.DrawRay (transform.position, transform.up, Color.green);

		if(hit == null)
		{
			Debug.Log ("OmgZ the world is going down!");
		}

		if(hit != null)
		{
			string tag = hit.transform.tag;
			Debug.Log (tag);
			if(hit.collider.gameObject.tag == "Border")
			{
				Debug.Log ("Border hit!");
			}
		}
	}
	
	/*private void InputListen()
	{
		prevLoc = curLoc;
		curLoc = transform.rotation;
		
		if(Input.GetKey(KeyCode.A))
			curLoc.y -= 1 * Time.fixedDeltaTime;
		if(Input.GetKey(KeyCode.D))
			curLoc.y += 1 * Time.fixedDeltaTime;
		if(Input.GetKey(KeyCode.W))
			curLoc.z += 1 * Time.fixedDeltaTime;
		if(Input.GetKey(KeyCode.S))
			curLoc.z -= 1 * Time.fixedDeltaTime;
		
		transform.rotation = curLoc;
		
	}*/
}

Thanks btw ! :slight_smile:

Anyone ?

Please make sure that you have the correct line numbers in the error message. The relevant line you provide is wrong:

Here’s the current error with the script above:

NullReferenceException: Object reference not set to an instance of an object
PCMovementScript.CheckRaycast () (at Assets/Scripts/PCMovementScript.cs:88)
PCMovementScript.Update () (at Assets/Scripts/PCMovementScript.cs:17)

You ran into a Unity documentation bug. You can’t use:

if (hit != null) {
	...
}

Instead, you need to do the following:

if (hit.transform != null) {
	...
}
1 Like

RaycastHit2D has an implicit operator to convert to bool therefore you can do this:

if (hit)
{
 ...
}

… implemented like this …

// Implicitly convert a hit to a boolean based upon whether a collider reference exists or not.
public static implicit operator bool (RaycastHit2D hit) { return hit.collider != null; }

Because it is a structure, it cannot be NULL but if it’s “invalid” i.e. it contains no hit information then the “collider” property will be NULL (as will the “rigidbody” property and the “transform” property which are driven off the “collider” property).

Hope this helps.

1 Like

Great informations! Thanks a lot!

Edit: Yes, it can certainly not be null. But the documentation compares against null as well. If Unity has implicit operators, it would be pretty charming to have it in the documentation :slight_smile:

I have the exact same problem but all of these fixes do nothing to change the exception. Each seems to be the answer but to no avail :face_with_spiral_eyes:. Sorry if I am hijacking but if anyone can help that would be great.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SelectChar : MonoBehaviour {

    public GUIStyle font;
    public int    selectedPlayer;
    // The left marker out of visible scence
    public Transform markerLeft2;
    // The left marker of visible scence
    public Transform markerLeft;
    // The middle marker of visible scence
    public Transform markerMiddle;
    // The right marker of visible scence
    public Transform markerRight;
    // The right marker out of visible scence
    public Transform markerRight2;

    // The characters prefabs to pick
    public Transform[] charsPrefabs;

    // The game objects created to be showed on screen
    private GameObject[] chars;

    // The index of the current character
    public static int currentChar = 0;

    void Start()
    {
    // We initialize the chars array
    chars = new GameObject[charsPrefabs.Length];

    // We create game objects based on characters prefabs
    int index = 0;
    foreach (Transform t in charsPrefabs)
        {
        chars [index++] = GameObject.Instantiate (t.gameObject, markerRight2.position, Quaternion.identity) as GameObject;
        //int pos = t.gameObject.name.IndexOf("("); // find the left parenthesis position...
        //t.name = t.gameObject.name.Substring(0, pos); // and get only the substring before it    
        }
    }

    void Update()
    {

            if ( Input.GetMouseButtonDown( 0 ) )
            {
                Vector2 worldPoint = Camera.main.ScreenToWorldPoint( Input.mousePosition );
                RaycastHit2D hit = Physics2D.Raycast( worldPoint, Vector2.zero );
                if ( hit )            
                {
                    Debug.Log( hit.collider.name );
                }
                                    
                if (hit.collider.name == "Milo(Clone)")
                                SelectedCharacter1 (); //Sends this click down to a function called "SelectedCharacter1(). Which is where all of our stuff happens.

                if (hit.collider.name == "Odin(Clone)")
                                SelectedCharacter2 ();

                if (hit.collider.name == "Lucious(Clone)")
                                SelectedCharacter3 ();

                if (hit.collider.name == "Drake(Clone)")
                                SelectedCharacter4 ();

                if (hit.collider.name == "Andrac(Clone)")
                                SelectedCharacter5 ();
                else {
                
                    return;           
                    }
            }     
    }
    void SelectedCharacter1() {
        Debug.Log ("Character 1 SELECTED"); //Print out in the Unity console which character was selected.
        selectedPlayer = 0;
        PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
        LoadLevel.StartGame ();
    }

    void SelectedCharacter2() {
        Debug.Log ("Character 2 SELECTED");
        selectedPlayer = 1;
        PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
        LoadLevel.StartGame ();
    }

    void SelectedCharacter3() {
        Debug.Log ("Character 3 SELECTED");
        selectedPlayer = 2;
        PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
        LoadLevel.StartGame ();
    }

    void SelectedCharacter4() {
        Debug.Log ("Character 4 SELECTED");
        selectedPlayer = 3;
        PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
        LoadLevel.StartGame ();
    }

    void SelectedCharacter5() {
        Debug.Log ("Character 5 SELECTED");
        selectedPlayer = 4;
        PlayerPrefs.SetInt("selectedPlayer", (selectedPlayer));
        LoadLevel.StartGame ();
    }


    void OnGUI() {


        // Here we create a button to choose a next char
        if (GUI.Button(new Rect(10, (Screen.height - 50) / 2, 100, 50), "Previous")) {
            currentChar--;
        
            if (currentChar < 0) {
                currentChar = 0;
            }
        }
    
        // Now we create a button to choose a previous char
        if (GUI.Button(new Rect(Screen.width - 100 - 10, (Screen.height - 50) / 2, 100, 50), "Next")) {
            currentChar++;
        
            if (currentChar >= chars.Length) {
                currentChar = chars.Length - 1;
            }
        }
    
        // Shows a label with the name of the selected character
        GameObject selectedChar = chars[currentChar];
        string labelChar = selectedChar.name;//.Replace ("(clone)", "");//.Trim();
            //.Replace ("(clone)", "").Trim();
        GUI.Label(new Rect((Screen.width -100 ) / 2, 20, 100, 50), labelChar.Replace("(Clone)","").Trim (),font);
    
        // The index of the middle character
        int middleIndex = currentChar;
        // The index of the left character
        int leftIndex = currentChar - 1;
        // The index of the right character
        int rightIndex = currentChar + 1;
    
        // For each character we set the position based on the current index
        for (int index = 0; index < chars.Length; index++) {
            Transform transf = chars[index].transform;
        
            // If the index is less than left index, the character will dissapear in the left side
            if (index < leftIndex) {
                transf.position = Vector3.Lerp(transf.position, markerLeft2.position, Time.deltaTime);
            
                // If the index is less than right index, the character will dissapear in the right side
            } else if (index > rightIndex) {
                transf.position = Vector3.Lerp(transf.position, markerRight2.position, Time.deltaTime);
            
                // If the index is equals to left index, the character will move to the left visible marker
            } else if (index == leftIndex) {
                transf.position = Vector3.Lerp(transf.position, markerLeft.position, Time.deltaTime);
            
                // If the index is equals to middle index, the character will move to the middle visible marker
            } else if (index == middleIndex) {
                transf.position = Vector3.Lerp(transf.position, markerMiddle.position, Time.deltaTime);
            
                // If the index is equals to right index, the character will move to the right visible marker
            } else if (index == rightIndex) {
                transf.position = Vector3.Lerp(transf.position, markerRight.position, Time.deltaTime);
            }
        }
    }

}

NullReferenceException: Object reference not set to an instance of an object
SelectChar.Update () (at Assets/Scripts/SelectChar.cs:56)

Line 56 is bolded, underlined, and italiced above:-

if (hit.collider.name == “Milo(Clone)”)

Edited to get the code lines correct.

Edit 2 I have found the error, in my enthusiasm to debug I wrapped it leaving the if collider code on the outer layer which meant the check for null was being missed in the revisions. Thanks for the solutions guys problem solved.

Thank you so much for this, it helped me solve my problem!