Unity raycast how and when to use

When I first started game development with Unity, I used to stay away from some of the functions that I don’t understand. Unity Raycast is one such function. When I learnt about Raycast, 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 below line of code by the end of the post.

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

What is Raycast in Unity?

Raycast as the name suggests is to casts 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 Raycasts will not detect colliders for which the Raycast origin is inside the collider.

Raycasting in Unity

You need to know about a few components before making a proper 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 casted ray will travel. It is always a better option to specify range as it helps in performance.

Raycasts from Camera

Let’s cast a basic ray from our camera in the forward direction. All you need to do is to attach a script to the camera and add the below line of code to the script

using UnityEngine

public class ExampleClass : MonoBehaviour
{
    
    void FixedUpdate()
    {
         RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, 10))
        {
            
            Debug.Log(hit.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 hit 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 about 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 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 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 Ray casted, 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 Unity 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 Raycasts.
  2. Try to avoid multiple Raycasts 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);
    }

Unity raycast demo

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

We will skip the basics like how to create a project in Unity. 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 camera so, lets 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 script to camera

  1. Create a new script component on the camera.
  2. Add the script from 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");
        }
    }
}

make raycast visible in the 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 little silent on 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 Ray visible in 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 Unity3D

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 question, you can leave them in the comment section below.

Leave a Reply

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