Complete Raycast tutorial for Unity

When I first started game development with Unity3D, I used to stay away from some of the functions that I didn’t understand. Unity Raycast is one such function. When I learnt about Raycasting, then I understood the importance and how Raycast can make a lot of things easier. So, in this post we will be going through some basics of Raycast and then also see some code samples that you can use in your game.

Our objective is to make sure you understand the line of code below by the end of the post.

Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask)

What is Raycast in Unity?

Raycast as the name suggests is to cast a ray from one position to another. It’s simply like a laser beam in the gaming world. In Unity, Raycast uses mathematical variables like position, range etc. to make this possible. You can specify from where to where you want the ray to be cast or you can also cast a ray for an infinite distance in a particular direction. You can also ignore layers during ray casting. Raycast requires colliders in order to interact with the gameobjects. Any gameobject without colliders will not trigger a hit. The object hit will be available in Raycasthit.

When is Raycast used?

Raycast can be used for many purposes in gaming. Mostly it is used to find objects in a particular direction or for shooting. But, one thing to be kept in mind while using Raycast is the effect on performance. If you cast multiple rays of infinite length then your game performance is going to suffer. The general practice is to Raycast when some action happens. For example, in a shooting script Raycast is done only when the mouse button is pressed.

An important thing to note is Raycast will not detect colliders for which the Raycast origin is inside the collider.

Basics of Raycasting in Unity

You need to know about a few components before making a proper Physics.Raycast.

  1. RaycastHit – this variable type is used to store the information received from the Raycast.
  2. Layermask- this is used to mask one particular layer you want the ray to interact or ignore.
  3. Range – this specifies the range up to which the ray will travel. It is always a better option to specify range as it helps in performance.

Unity Raycast Tutorial

Now that you understand how Raycast works in Unity3D. Let’s try it out in a demo scene. We will create two cubes and set them into two different layers. We will try to hit the cube on the back. Here is the video of what we are going to do.

We will skip the basics like how to create a project in Unity3D. I am assuming you already have a project to cast the ray.

Step1: Creating game objects

  1. Go to hierarchy window.
  2. Select Create (+)>3D object>cube. Add two cubes.
  3. We will be casting the ray from the camera so, let’s align the cube one behind the other from the cameras preceptive. You should be able to see only one cube in the game window.
Raycast demo object setup

Step2: Adding layers

  1. Let’s create two layers called enemy and friend.
  2. Click layers dropdown on any Gameobject’s inspector view.
  3. Select Add layer and enter the required details.
  4. Assign the cube in front of camera as friend and the cube on the back as enemy.
Layer setup details

Step3: Adding the camera script

  1. Create a new script component for the camera.
  2. Add the script below. Remember the script name and the class name should be the same.
  3. Save and play. We are Raycasting to a distance of 10 Units. So, the enemy must be destroyed only at 10 Unit distance.
using UnityEngine;
public class for_raycasting : MonoBehaviour
{
    
    void FixedUpdate()
    {
        int layerMask = 1 << 6;
        layerMask = ~layerMask;
         RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, 10,layerMask))
        {
            
            Destroy(hit.collider.gameObject);
        }
        else
        {
            
            Debug.Log("Did not Hit");
        }
    }
}

In the above script we are Raycasting to a range of 10 Units in the forward direction. “Physics.Raycast” returns true if the ray hits a collider or else it will return false.

In the Raycast syntax the first input is the origin place, second is the direction, third is the output and fourth is the range. We can also add another variable layermask to it. We will discuss it in the next section.

Should you Raycast in Update or Fixed Update?

The reason I used fixed update is because Raycast is a physics property and also it will help you to stop Raycasting when you pause your game in Unity3D with timescale.

Raycasting between two points

You need to tweak the above code a little to cast a ray between two points. I am assuming you are attaching this script to point1.

if (Physics.Raycast(transform.position, point2.transform.position-transform.position , out hit, 10))
        {
            
            Debug.Log("object is at 10 units range");
        }

Alternatively, you can use the Linecast function to cast a line between two points. Linecast will return true if there are any objects with colliders between the two points. You can use the layermask to ignore some objects.

if (Physics.Linecast(transform.position, point2.transform.position))
        {
            Debug.Log("colliders found between the two position");
        }

Raycasting from mouse point

Mouse point is a little bit trickier than other things in Unity. The device screen is 2D and the game world is 3D. So, you need to convert the mouse point to game world position. You need to use the camera for this purpose. Go ahead and tag your camera as main camera before proceeding.

Converting mouse position to ray

Ray ray = Camera.Main.ScreenPointToRay(Input.mousePosition);

Cast a ray with the range and hit attribute

if (Physics.Raycast(ray, out hit, 10))
{
    Debug.Log(hit.gameobject);
}

How to ignore a layer in Unity Raycast?

It often comes to a situation where we don’t want the ray to hit everything. For example, implementing friendly fire in an FPS game. You don’t want your fire to hit friends so, you can just add the friendly players to a layer and ignore them from Raycast. To ignore a layer from the Raycast, you just need to add the bit mask of the layer index to your Raycast expression. You need to add the variable shown below and modify the if statement from the above code. You can also get more information on layermask from Unity3D manual.

The layerMask variable needs to be inverted inside the Update function.

int layerMask = 1 << 5;//bit mask for layer number 5
layerMask=~layerMask
//add the 2nd line if you want to ignore layer 5 if not added it will Raycast only to layer 5
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, 10, layerMask))

Raycasthit

Raycasthit contains all details about the object hit by the Raycast. If the Raycast does not hit any object then Raycasthit returns “Null”. You can get the following details about the hit object.

  1. Gameobject.
  2. Collider attached to the object.
  3. Distance of the object from the origin.
  4. Transform
  5. Rigidbody details

Is Raycasting performance expensive?

In Unity3D, Raycast is a very helpful function but needs to be used carefully. Many developers avoid Raycast in order to boost performance. But you need not worry unless you are making a very performance hungry game. Just keep in mind a few things and you should be good.

  1. Never forget to provide the range of Raycast.
  2. Try to avoid multiple Raycast simultaneously.
  3. Use Raycast with a condition like button press inside Update.
  4. Avoid Raycasting against a mesh collider.
  5. Use layer mask effectively.

Raycastall in Unity3D

If you are looking for a list or array of objects hit by a Raycast, then Raycastall is your best option.

 RaycastHit[] hits;
 hits = Physics.RaycastAll(transform.position, transform.forward, 50.0F);
    foreach(Raycasthit i in hits)
    {
       Debug.Log(i.gameobject);
    }

Make the ray visible in the Unity editor

Draw ray in Unity editor

You can use Debug.DrawRay(origin,direction,color) to draw a ray in the Unity editor. But to make it similar to the ray we have cast you need to use the same ray.

Normally to cast a ray, you don’t need to create a ray variable. You can put the Raycast expression in an if statement and it will return true if it hits something. To draw the ray, we will create a ray variable that takes the origin and direction as input. Then we draw a ray with these properties.

using UnityEngine;
public class Raycasting : MonoBehaviour
{
    
    RaycastHit hit;
    void FixedUpdate()
    {
        Ray ray=new Ray(transform.position, transform.TransformDirection(Vector3.forward));
        
        if (Physics.Raycast(ray, out hit, 10))
        {
            
            Debug.Log(hit.collider);
        }
        else
        {
            Debug.DrawRay(ray.origin, ray.direction*10f,Color.red);
            
            Debug.Log("Did not Hit");
        }
    }
}

Length of Debug.DrawRay

Unity3D docs is a little silent in this area. It doesn’t clearly state how to control the length of the ray in Debug.DrawRay. Length of the ray depends on the magnitude of the direction vector. In the above example, we have used a unit vector and multiplied it with the required length. You cannot multiply it with Mathf.Infinity to make it infinite in length. it doesn’t work. You can only Raycast with infinite length but cannot draw a ray. You can use a big number like 100000f to solve the problem.

Debug.DrawRay(ray.origin, ray.direction*10000f,Color.red);

Make the Ray visible in your game

The above section was about making the ray visible in Unity editor but if you build the game the ray won’t be visible in the game. If you want the ray to be visible in your game then you need to use the line renderer. You can set the start and end point as shown in the script below.

using UnityEngine;
public class Raycasting : MonoBehaviour
{
    LineRenderer lin;
    
    RaycastHit hit;
    void Start()
    {
        lin=GetComponent<LineRenderer>();
    }
    void FixedUpdate()
    {
        Ray ray=new  Ray(transform.position,transform.TransformDirection(Vector3.forward));
        
        if (Physics.Raycast(ray, out hit, 10))
        {
            
            Debug.Log(hit.collider);
        }
        else
        {
            lin.SetPosition(0,ray.origin);
            lin.SetPosition(1,ray.direction*10f);
            
            Debug.Log("Did not Hit");
        }
    }

Raycast2D in Unity

Raycasts can be used in 2D games too but a normal Raycast will not collide with 2D colliders. You need to use Raycast2D for this purpose.

You just need to replace all the 3D components in the code with 2D.


using UnityEngine
public class ExampleClass : MonoBehaviour
{
    
    void FixedUpdate()
    {
         RaycastHit2D hit;
        if (Physics2D.Raycast2D(transform.position, transform.TransformDirection(Vector2.forward), out hit, 10))
        {
            
            Debug.Log(hit.gameobject);
        }
        else
        {
            
            Debug.Log("Did not Hit");
        }
    }
}

Hope the post covered all the required aspects of Raycast. If you have any questions, you can leave them in the comment section below.

2 thoughts on “Complete Raycast tutorial for Unity”

  1. Thanks for the In-depth tutorial on Unity Raycast. I was struggling to make the ray visible in my game. This tutorial helped me a lot.

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.