Can Someone Explain RayCasting to me?

I am going through this tutorial series on youtube and the youtuber starts using raycasting in his code. I understood everything up to when he started using raycasting.I understand raycasting casts a line between a point of origin and a certain distance. I also get that the code I have copied is about finding the distance between a point of origin and a point of collision, but I don’t understand how his code does that. I put the line of code I do not understand in the top, but if someone could provide a description of how this line of code fits in with the rest of it I would appreciate it. Thank you very much for the help! I Here is the code,

"if (Physics.Raycast (ray, out hit, moveDistance, collisionMask, QueryTriggerInteraction.Collide)) // This is the line of code I do not understand. Particularly the “out hit” part.

using UnityEngine;
using System.Collections;

public class Projectile : MonoBehaviour {

    public LayerMask collisionMask;
    float speed = 10;

    public void SetSpeed (float newSpeed){
        speed = newSpeed;
    }


    void Update () {
        float moveDistance = speed * Time.deltaTime;
        CheckCollisions (moveDistance);
        transform.Translate (Vector3.forward * Time.deltaTime * speed);
    }

    void CheckCollisions (float moveDistance) {
        Ray ray = new Ray (transform.position, transform.forward);
        RaycastHit hit;

        if (Physics.Raycast (ray, out hit, moveDistance, collisionMask, QueryTriggerInteraction.Collide)) {   
            OnHitObject (hit);    
        }
    }

    void OnHitObject (RaycastHit hit){

        print (hit.collider.gameObject.name);
        GameObject.Destroy (gameObject);
       
    }
}

A Raycast does some math to determine what object(s) the line intersects with. The out keyword tells the compiler that the method will return a value in that parameter. It allows passing a reference to the value rather than the value itself, which means the method can change the value. So Raycast calculates the object and returns information about the collision by filling in fields in the hit parameter.

2 Likes
if (Physics.Raycast (ray, out hit, moveDistance, collisionMask, QueryTriggerInteraction.Collide))

Okay, let’s break it down.

The whole thing is inside an IF statement. As I’m sure you know, IF statements require a boolean value in order to work. For our convenience, Physics.Raycast returns True if it hit ANYTHING, and False if it hit nothing.

Next we have the actual Raycast function. The first parameter is a Ray. A Ray defines the origin and direction that the line will go to check for any intersecting colliders. You defined the Ray object before this line, and passed it in.

Next we have the “out hit” part. Before this line, you defined “RaycastHit hit” but didn’t assign it. What the “out” keyword means, is that after that function has run, there will be values coming OUT of the function, and into that variable. Since Physics.Raycast returns true if it hit something, that guarantees that when the IF statement moves into the code block, that “hit” variable has stuff in it. So then inside the IF, you have “OnHitObject(hit)” and you pass the RaycastHit “hit” object with the new info about what the raycast hit. It’s like a return value assigned to a variable passed in as a parameter, instead of returning from the function itself.

moveDistance, the distance the line will extend based on the direction in the Ray.

Next you have the collisionsMask, which simply defines the layers that the raycast should be able to hit. It will ignore anything not in that LayerMask (you define in the inspector).

Next you have the QueryTriggerInteraction.Collide which just means to hit all colliders, and wont ignore triggers.

13 Likes

So basically if I am getting this right, the “out hit” section makes sure that my “RaycastHit hit” variable is actually assigned to something while also guaranteeing that that something has collided with another game object. Because of this, I don’t have to make another if statement in the OnHitObject function.

1 Like

Thanks for the help!

Yes I think you’ve got it!

Key things to note:

  • Physics.Raycast returns True when it hit something, False if it hit nothing
  • “out hit” will only be assigned if Physics.Raycast returns True
  • Wrapping Physics.Raycast in an IF statement allows you to execute code only if the raycast hit something
  • Therefore “out hit” can be assumed to have data inside the IF statement
3 Likes

Okay, so out hit just sends information to the hit variable if Physics.Raycast returns true, or in other words, if the ray collides with something.

That is correct.

“out” means that the variable is directly editable from within the function (and must be assigned a value within, which could be “null”), whereas normally the function would only have a copy of the data passed in. So instead of just a value going in, it’s the variable itself.

You can test this out yourself like this:

using UnityEngine;

public class Example : MonoBehaviour {

    // two class level variables
    Vector3 myVar1;
    Vector3 myVar2;

    public void Start() {
        myVar1 = Vector3.right; // 1,0,0
        myVar2 = Vector3.up; // 0,1,0

        print("Before:");
        print("Varible 1: " + myVar1);
        print("Varible 2: " + myVar2);

        CoolFunction(out myVar1, myVar2); // notice the 'out' keyword

        print("After:");
        print("Varible 1: " + myVar1);
        print("Varible 2: " + myVar2);
    }

    // notice the 'out' keyword here as well
    public void CoolFunction(out Vector3 v3Variable, Vector3 v3Value) {
        v3Variable = Vector3.one; // 1,1,1
        v3Value = Vector3.one; // 1,1,1
    }
}

There is another similar parameter keyword “ref”, which is the same as “out” only requires that the variable be assigned something before going into the function (and doesn’t require it to be assigned within).

5 Likes

I just finished messing around with your code and I think I get it. v3Variable changes myVar1 because of the “out” keyword whereas v3Value does not change myVar2 because there is no out keyword for that parameter in the function.

Thanks!

1 Like

This is helpful. For those too lazy to run the code, the output is…
Before:
Variable 1: (1.0, 0.0,0.0)
Variable 2: (0.0, 1.0, 0.0)
After:
Variable 1: (1.0, 1.0, 1.0)
Variable 2: (0.0, 1.0, 0.0)

As a mnemonic, I’m going to remember this as “out” allows you to pass a variable into a function and get a value back out.

I’m still fuzzy on why out is needed with RaycastHit hit object, but I’m assuming that hit acts like a function and/or it is necessary because it is in the if conditional.

2 Likes