Different types of raycasts in Unity

Physics class in the Unity engine has many methods related to detecting collisions with other physical objects. One of such methods is Raycast, but do you know that you can also cast different shapes?

Let’s explore the world of physics casts and see know to use them!

Raycast ?

The most popular method would be Raycast method.

This method “shoots” the ray from the origin position in a given direction. We can limit this ray’s length if we want to, but by default, the length is infinite.

Code example:

using UnityEngine;

/// <summary>
/// Use example for Raycast method.
/// </summary>
public class RayExample : MonoBehaviour
{
    /// <summary>
    /// Called each physics frame.
    /// </summary>
    private void FixedUpdate()
    {
        Ray ray = new Ray(transform.position, transform.forward); // Defines ray

        RaycastHit hitResult; // Stores the result

        // Call Raycast
        if (Physics.Raycast(ray, out hitResult)) {
            Debug.Log($"Raycast hitted: {hitResult.collider.name}");
        }
    }
}

Linecast ?

The Linecast method is really similar to the Raycast method.

The difference between those two is the definition. In Raycast, we are defining the start position and direction. In Linecast, we define the start and end position.

This method checks if there is something in between those two points.

Code example:

using UnityEngine;

/// <summary>
/// Use example for Linecast method.
/// </summary>
public class LineExample : MonoBehaviour
{
    /// <summary>
    /// Called each physics frame.
    /// </summary>
    private void FixedUpdate()
    {
        Vector3 startPosition = transform.position; // Line begin
        Vector3 endPosition = startPosition + Vector3.right * 10; // Line end

        RaycastHit hitResult; // Stores the result

        // Call Linecast
        if (Physics.Linecast(startPosition, endPosition, out hitResult))
        {
            Debug.Log($"Linecast hitted: {hitResult.collider.name}");
        }
    }
}

Volume casts ?

Until now, we were only casting point/line. Time to start casting volumes!

They are helpful when Raycast doesn’t give you enough precision. Sometimes you would like to check if your character will fit somewhere or the object your holding will hit something on its way.

BoxCast ?

The first volume cast will be the BoxCast method.

To better understand how this method is working, imagine a box in an empty space. Now imagine you’re pushing this box forward, and you wait for it to collide with something.

That’s exactly what the BoxCast method is. It doesn’t matter if this box just scratches its edge or barely touches something. You will know about it.

With this method, you’ll have to pass some additional parameters that define the box – position, size, and rotation.

Code example:

using UnityEngine;

/// <summary>
/// Use example for BoxCast method.
/// </summary>
public class BoxExample : MonoBehaviour
{
    /// <summary>
    /// Called each physics frame.
    /// </summary>
    private void FixedUpdate()
    {
        Vector3 boxPosition = transform.position; // Box position
        Vector3 boxHalfSize = Vector3.one * 0.5f; // Half size of the box
        Quaternion boxRotation = transform.rotation; // Box rotation

        Vector3 castDirection = transform.forward; // Cast direction

        RaycastHit hitResult; // Stores the result

        // Call BoxCast
        if (Physics.BoxCast(boxPosition, boxHalfSize, castDirection, out hitResult, boxRotation))
        {
            Debug.Log($"BoxCast hitted: {hitResult.collider.name}");
        }
    }
}

CapsuleCast ?

The next type of shape cast is the CapsuleCast method.

This method works the same way as BoxCast, but of course, with Capsule rather than Box.

The only quirky thing about this method would be parameters to define capsule.

You have to pass a position of the “bottom” sphere and “top” sphere, and of course, the radius of a capsule.

Code example:

using UnityEngine;

/// <summary>
/// Use example for CapsuleCast method.
/// </summary>
public class CapsuleExample : MonoBehaviour
{
    /// <summary>
    /// Called each physics frame.
    /// </summary>
    private void FixedUpdate()
    {
        Vector3 bottomSpherePosition = transform.position; // Position of the bottom capsule sphere
        Vector3 topSpherePosition = Vector3.one * 0.5f; // Position of the top capsule sphere
        float radius = 0.5f; // Capsule radius

        Vector3 castDirection = transform.forward; // Cast direction

        RaycastHit hitResult; // Stores the result

        // Call CapsuleCast
        if (Physics.CapsuleCast(bottomSpherePosition, topSpherePosition, radius, castDirection, out hitResult))
        {
            Debug.Log($"CapsuleCast hitted: {hitResult.collider.name}");
        }
    }
}

SphereCast ?

The last type is Sphere. Similarly to the box and capsule variant, the SphereCast method will cast spheres!

In this method, we’re only passing the start position and radius of the sphere that we’re casting.

Code example:

using UnityEngine;

/// <summary>
/// Use example for SphereCast method.
/// </summary>
public class SphereExample : MonoBehaviour
{
    /// <summary>
    /// Called each physics frame.
    /// </summary>
    private void FixedUpdate()
    {
        Vector3 spherePosition = transform.position; // Sphere position
        float radius = 0.5f; // Sphere radius

        Vector3 castDirection = transform.forward; // Cast direction

        RaycastHit hitResult; // Stores the result

        // Call SphereCast
        if (Physics.SphereCast(spherePosition, radius, castDirection, out hitResult))
        {
            Debug.Log($"SphereCast hitted: {hitResult.collider.name}");
        }
    }
}

Rigidbody’s Sweep Test ?

Whenever methods mention before were not enough, you call also cast your physical object. For that, you need to use Rigidbody.SweepTest method.

But note, that this method will only work when a primitive collider or a convex mesh is attached to the rigidbody.

Thanks to this method, you have a little bit more flexibility with volumetric casts.

Code example:

using UnityEngine;

/// <summary>
/// Use example for SweepTest method.
/// </summary>
public class SweepExample : MonoBehaviour
{
    // Reference to the rigidbody component.
    private Rigidbody rb;

    /// <summary>
    /// Called at the beggining.
    /// </summary>
    private void Start()
    {
        rb = GetComponent<Rigidbody>(); // Get reference to the rigidbody component.
    }


    /// <summary>
    /// Called each physics frame.
    /// </summary>
    private void FixedUpdate()
    {
        Vector3 castDirection = transform.forward; // Cast direction

        RaycastHit hitResult; // Stores the result

        // Call SweepTest
        if (rb.SweepTest(castDirection, out hitResult))
        {
            Debug.Log($"SweepTest hitted: {hitResult.collider.name}");
        }
    }
}

Bonus – CastAll and NonAlloc ?

There are two additional variants to all methods mentioned above – one for receiving all collisions with a cast, and the second which do the same, but you have to provide the buffer for the results.

You can think about CastAll methods as methods that instantiate a new array for results and call NonAlloc methods. At least that’s how I see it… ?

Summary ?

So that’s it about raycasts. If you want to check the documentation go to the Physics and Rigidbody classes.

If you liked the post or have anything more to add, leave the comment in the comment section below!

And if you want to be notified about future content on my blog, you can sign up for my newsletter!

Thanks for reading, and see you next time! ?

4.3 7 votes
Article Rating
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Jordan
Jordan
2 years ago

Hey Patryk,
Thanks for this writeup. Any idea on the performance ranking of Unity’s raycast methods? For example, is SphereCast any less performant than a Linecast?
Thanks!

2
0
Would love your thoughts, please comment.x
()
x