3 Raycasts, 1 Object

Hi forum,

I was playing with code for my upcoming game and decided to cast multiple rays in one function. But I stumbled upon the problem that sometimes rays generate such error:

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

Does anyone could tell what is the possible reason for that. My method code is:

	public void DeathCollision()
	{
		Vector3 frntCol = transform.TransformDirection(Vector3.right);
        RaycastHit hit;
		RaycastHit hitTop;
		RaycastHit hitBot;

        Debug.DrawRay(transform.position, frntCol * 1, Color.green, 5);
		Debug.DrawRay(transform.position + new Vector3(0, transform.localScale.y/2f, 0), frntCol * 1, Color.red, 5);
		Debug.DrawRay(transform.position + new Vector3(0, -transform.localScale.y/2f, 0), frntCol * 1, Color.blue, 5);
		
		bool midRay = Physics.Raycast(transform.position, frntCol, out hit, 1.0f);
		bool topRay = Physics.Raycast(transform.position + new Vector3(0, transform.localScale.y/2f, 0), frntCol, out hitTop, 1.0f);
		bool botRay = Physics.Raycast(transform.position + new Vector3(0, -transform.localScale.y/2f, 0), frntCol, out hitBot, 1.0f);

        if (midRay || topRay || botRay)
        {
           //Error happens here in this conditional statement. I presume that hit is not being populated for some reason
            if(	hit.transform.gameObject.layer == 8 ||
				hitTop.transform.gameObject.layer == 8 ||
				hitBot.transform.gameObject.layer == 8)
            {
                Debug.Log("DeathCollision");

                transform.Translate(Vector3.right * 1.0f);
                transform.Translate(Vector3.up * 2.0f);
                rigidbody.velocity = Vector3.zero;
            }
			else
			{
				Debug.Log ("Acceleration");
				
				transform.Translate(Vector3.right * 1.0f);
                transform.Translate(Vector3.up * 2.0f);
			}
        }
	}

(P.S when I have only one raycast everything works with no problems)

I don’t have Unity with me, but I suspect…

if (midRay || topRay || botRay)

This will return true if only one of the rays hits. So let’s assume that midRay hits but top and bot Rays do not.

Then in this line…

if( hit.transform.gameObject.layer == 8 ||

                hitTop.transform.gameObject.layer == 8 ||

                hitBot.transform.gameObject.layer == 8)

hitTop and hitBot would not be assigned to anything, because the ray didn’t hit. If you plan only checking all of them, you should do

midray  topRay  botRay

Erik

Thanks for the reply.

I am not planning to check if they were all hit at the same time. The idea is to check if one of them was hit or not, that is why I am using logical operator || (logical or). In other words, to satisfy my condition only one of these Raycasts should hit something.

Any more thoughts maybe? :face_with_spiral_eyes:

But that is the reason it does not work
only one of the rays hit → only one of the RaycastHits exists, but you still try to operate with them (they are null)

Ok it makes sense now… So what would be the alternative approach then? :slight_smile:

How about this?

        public void DeathCollision()
        {
//Move these 3 raycasts
            //bool midRay = Physics.Raycast(transform.position, frntCol, out hit, 1.0f);
            //bool topRay = Physics.Raycast(transform.position + new Vector3(0, transform.localScale.y/2f, 0), frntCol, out hitTop, 1.0f);
            //bool botRay = Physics.Raycast(transform.position + new Vector3(0, -transform.localScale.y/2f, 0), frntCol, out hitBot, 1.0f);
//into this if test, but all using the same raycastHit parameter
            if (Physics.Raycast(transform.position, frntCol, out hit, 1.0f) ||
Physics.Raycast(transform.position + new Vector3(0, transform.localScale.y/2f, 0), frntCol, out hit, 1.0f) ||
Physics.Raycast(transform.position + new Vector3(0, -transform.localScale.y/2f, 0), frntCol, out hit, 1.0f) )
            {
//Because the if test uses ORs, it stops performing them once one returns true,
//and the single hit param will contain the information from that ra
                if( hit.transform.gameObject.layer == 8){
//then these other hit's are not needed
                    //hitTop.transform.gameObject.layer == 8 ||
                    //hitBot.transform.gameObject.layer == 8)
...snip

Well that looks nice… Thanks, I will try it :slight_smile: