What is Raycasting?
Raycasting is commonly used in video game development for things such as determining line of sight of the player or the AI, where a projectile will go, creating lasers and more. A raycast is, essentially, a ray that gets sent out from a position in 3D or 2D space and moves in a specific direction. Unity 3D has built-in functions that can be used to implement a Raycast in your game.
Raycast in Unity Tutorial
In this post, I will be giving examples of how to implement a Raycast in Unity 3D and how to use the Raycast information to determine if an object is in line of sight of the user and if we can interact with that object.
First of all, I’m going to assume that you already have a scene setup with a character controller of some kind that you can use. If you don’t, then go ahead and create a new scene, create some kind of plane you can walk around on, and put a character controller in the scene. If you don’t have a controller, then import the standard assets/characters package and drag and drop one of the prefab controllers into your scene.
Once you have your basic scene setup, we’ll create a cube by going to GameObject → 3D Object → Cube, as seen here:
Move the cube somewhere close to your controller so we can quickly and easily test any functionality we are working on. Once the cube is in place, we will want to create a custom tag for it. We will use the tag to determine what object we are looking when our Raycast hits it. Keep in mind that you can do this with an object name or any number of different variables.
For simplicity we’ll be using a tag to determine what we’re looking at. To create a custom tag, choose the cube in your scene and, in the inspector, click the Tag drop-down menu and choose “Add Tag…”
In the tag manager, click the + icon to create a new tag. Let’s call this tag “Interactive”.
Once the tag is created, click on the Cube again and choose the new Interactive tag from the tag drop down menu
Next, click on the cube and add a rigidbody component using the Add Component window:
Now that we’ve done that, let’s go ahead and implement the raycast. Choose your main camera in your scene and add a new C# Script component to it called LineOfSight:
Open up LineOfSight in your script editor. I have provided a screenshot of the code. You can copy it down and it should work: (If you have difficulty viewing the screenshot image below, click here.)
Declaring Variables in Script:
The first thing our script is doing is declaring four variables: RaycastHit, float, bool, rigidbody. We will use all of these to dictate our logic. In the Start function, we assign our boolean and our float values to their default values. This will happen when the game starts.
This is the first line in our Update function:
Debug.DrawRay(Camera.main.transform.position, Camera.main.transform.forward * rayLength, Color.red, 0.5f);
All this does is draw a Red line in our Scene View every frame that our game is running. The first parameter specifies the position where it starts, the second parameter is the direction it moves towards, the third parameter specifies the ray color, and the fourth parameter specifies the duration that the line is drawn on the screen. We do this primarily for debugging purposes. It allows us to actually see our raycast in our Scene View. We can see it in the Game View by clicking the “Gizmo” option in the Game View window as seen here:
Next, let’s look at what actually causes the raycast to happen:
if(Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out vision, rayLength))
This if statement essentially executes if a Raycast hits something. The condition for the if statement consists of a Physics.Raycast constructor, which takes four parameters in this example. The first parameter is the position the raycast starts at, which we specify as our camera position. The second parameter is the direction the raycast goes towards, which we specify as the forward direction of our camera. This ensures that wherever we look, the Raycast looks as well. The third parameter is the hit info parameter. It will provide further information about the raycast collision to the variable that we specify. In this example, we specify our RaycastHit variable called vision as the hit info argument. This means that our vision variable will contain collision information about the object that our Raycast hits. Lastly, the fourth parameter is the length of the raycast, which we specify as rayLength. We assigned rayLength in the Start function. It’s a public variable so we can modify it in the Inspector if we want to test different ray lengths.
Inside our raycast statement, we have a nested if statement that determines the tag of the object our raycast is hitting:
if(vision.collider.tag == “Interactive”)
If the object is tagged as “Interactive”, which we setup earlier, then we will execute something.
This line is simply outputting the name of the object we’re looking at to our Unity console. If we had some sort of UI Text display, we could easily print out the name of the object onto our UI display. You will notice when you are close enough and looking at the cube in your scene that the name of the cube will be output to the console like such:
Next, we have yet another nested if statement that only gets executed if we’re looking at an Interactive object:
if(Input.GetKeyDown (KeyCode.E) && !isGrabbed)
If our player is looking at an interactive object, this statement will allow the player to press E on the keyboard and execute something but only if we are NOT already grabbing something. So, once our player presses E and is allowed to pick up an object, we execute this code:
grabbedObject = vision.rigidbody;
grabbedObject.isKinematic = true;
isGrabbed = true;
We assigned grabbedObject to the rigidbody of the object that our raycast is hitting. Keep in mind this ONLY happens if we are looking at something tagged as Interactive. Remember that vision is our RaycastHit variable, which contains collision information about what our raycast is hitting. Next, we set the grabbedObject to kinematic, which disables physics interactions on the object. This will allow our player to pick up and move the object without it being affected by rotations, gravity, etc. After that, we set the parent of our grabbedObject to our main camera. This allows the grabbed object to move relative to our main camera. Lastly, we set isGrabbed to true so that our game knows that we are in possession of an object.
After that if statement, we have an else if statement:
else if(isGrabbed && Input.GetKeyDown(KeyCode.E))
This statement looks to see if the player is holding an object and if they press the E key. If both are true, then we drop the object by executing the following code within the if statement:
grabbedObject.transform.parent = null;
grabbedObject.isKinematic = false;
isGrabbed = false;
First, we set grabbedObject’s parent back to nothing so that it is no longer a child of our camera. Then, we set it to non-kinematic so that it interacts with physics again. Lastly, we set isGrabbed to false so that we can pick up another object if we want.
That does it for the code. At this point, you should be able to run the game and walk up to your cube and look at it. You should see its name output to your console, and you should be able to press E to pick it up and move around with it. You should then be able to press E again to drop the object.
And that concludes this simple introduction to Raycasts in Unity 3D. Hopefully you found it informative. Feel free to leave some feedback. Be sure to check out Studica on YouTube, Facebook, Twitter, and LinkedIn!
Blogger: Mark Philipp, Application Engineer at Studica
Share this Post