Unity Raycast: A Comprehensive C# Guide to Physics.Raycast

Unity Raycast is a very handy function and can be used for many purposes in games. Raycast is mainly used in FPS games for shooing and for object detection in AI. If you are making games with Unity then Raycast is a function you should master. Raycast can be used for both 2D and 3D games in Unity. In this tutorial, we will see what is Raycast and how you can use them effectively in games.

Syntax of a 3D Raycast

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

Parameters in Syntax

  1. Position to start the raycast from.
  2. Direction of Ray.
  3. Output parameter containing array of hit colliders.
  4. Length of Ray.
  5. Layers to include or exclude.

The Physics.Raycast function returns a boolean, which is true if the ray hit a game object.

What is Raycast in Unity?

Raycast in Unity is like a laser beam from one position to other. 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.

When to use Raycast?

Mostly Raycast 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.

Can Raycast hit objects without Colliders?

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.

An important thing to note is Unity Raycast will not detect colliders for which the Raycast origin is inside the collider. This limitation can be overcome using a setting in case of a 2D game.

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.

Raycasting in Unity

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: Setting up the scene for Raycast

  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.
Unity Raycast scene setup

Step2: Creating layers for Unity Raycast

  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 Raycast from Camera

  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.
using UnityEngine;
public class ForRaycasting : MonoBehaviour
{
    
    void FixedUpdate()
    {
        int layerMask = 1 << 6;//Since Friend is layer number 6
        layerMask = ~layerMask; //Inverted to ignore layer
        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. The fifth input is the LayerMask. We use this to skip the Friend layer and hit on the Enemy Layer. Let’s see another example on how to use LayerMask to ignore a layer in Unity.

If you do not hit anything then try increasing the range of the ray.

How to ignore a layer while Raycasting in Unity?

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 check out our detailed article on LayerMask.

The LayerMask variable needs to be inverted to ignore the layer.

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))

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 in Unity

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 in Unity

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);
}

Unity Raycasthit (Hit object details)

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?

Unity 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.

Unity Raycastall

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");
        }
    }

Unity Raycast in 2D

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

Raycast2D does not return true when hit but it returns the Hit object. The only change in the script will be you will get the hit object and then check for condition

Here is sample script on how a 2D Raycast will look like. You can check out the video above for more details on 2D Raycast.


using UnityEngine
public class raycast2dtest : MonoBehaviour
{
    RaycastHit2D hit;
    
    void FixedUpdate()
    {
         
         hit=Physics2D.Raycast(transform.position, Vector2.right);
                 
         Debug.Log(hit. Collider);
       
    }
}

Add a 2D collider to your gameobject which needs to interact with the Raycast. Also, Raycast in 2D can be set to detect its own Collider. You can enable this option from Edit>Project settings>Physics2d> Check Queries start in Colliders.

Unity Physics 2D settings

You can use the table below for understanding the difference between Unity Raycast in 3D and 2D.

Raycast 3DRaycast 2D
Physics.RaycastPhysics2D.Raycast
RaycastHitRaycastHit2D
Raycast returns a Boolean when ray hitsRaycast2D returns the Hit data when ray hits
Position and direction input should be Vector3Position and direction input should be Vector2
Interacts only with 3D collidersInteracts only with 2D colliders

Common Reasons why your Unity Raycast is not working

  1. Trying to hit the wrong type of Collider. A 3D Raycast cannot hit a 2D collider and vice versa.
  2. No collider attached to the object you are trying to hit.
  3. The object is set as inactive.
  4. Raycast is called within the Start function. You need to call it in the Update or FixedUpdate.
  5. Timescale is set to 0.
  6. The function name should be Physics.Raycast for a 3D game and Physics2D.Raycast for a 2D game.
  7. Length of the Ray is smaller than the distance between the objects.
  8. You are casting the Ray in the wrong direction.
  9. The Unity Raycast origin in inside the collider.

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

2 thoughts on “Unity Raycast: A Comprehensive C# Guide to Physics.Raycast”

  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.

%d bloggers like this: