Unity raycast presentation

Raycast and Overlap in Unity

In this comprehensive guide, we delve into the powerful tools of raycast and overlap within Unity, offering a detailed exploration of their functionalities and applications.

Table of Contents

Common Parameters

Every raycast shares common parameters:

  • Direction: a vector defining the direction of the ray.
  • Maximum distance: limits the length of the ray (Mathf.Infinity for no limit).
  • LayerMask: determines which layers the raycast will be applied to (See my article: Mastering LayerMask in Unity).
  • QueryTriggerInteraction: restricts or allows the possibility of hitting trigger colliders.

By default, each “Raycast” is provided with several methods:

  • Basic method (Raycast): the raycast stops as soon as a collider is found.
  • All method (RaycastAll): the raycast returns all the hit colliders.
  • NonAlloc method (RaycastNonAlloc): the raycast returns all the hit colliders, but the result array is passed directly as a parameter (buffer) for better performance.

Basic Raycast (Physics.Raycast) In Unity

To use Raycast, you can provide a position and a direction or directly provide a Ray. Here’s an example:


using UnityEngine;

public class RaycastMonoBehaviour : MonoBehaviour
{
    private void FixedUpdate()
    {
        // Raycast from the position of the game object going up with an infinite distance
        if (Physics.Raycast(transform.position, transform.up, out RaycastHit rayCastHit, Mathf.Infinity))
        {
            // Action with rayCastHit
        }

        // Alternative with a ray
        var ray = new Ray(transform.position, transform.up);

        if (Physics.Raycast(ray, out RaycastHit rayCastHit2, Mathf.Infinity))
        {
            // Action with rayCastHit2
        }
    }

    private void SampleWithAllParameters()
    {
        if (Physics.Raycast(transform.position, transform.up, out RaycastHit rayCastHit, Mathf.Infinity, Physics.AllLayers, QueryTriggerInteraction.Ignore))
        {
            // Do your raycast
        }
    }
}

Unity raycast

Raycast All

The RaycastAll method returns an array of RaycastHit:


private void RaycastAll()
{
    var hits = Physics.RaycastAll(transform.position, transform.up, Mathf.Infinity);

    // Return an array of RaycastHit
    for (int i = 0; i < hits.Length; i++)
    {
        var hit = hits[i];
    }
}

Raycast NonAlloc

To use RaycastNonAlloc, you need to instantiate a non-dynamic array with the maximum number of hits you can detect. The raycast stops if there are no more colliders or if the array is full. The output parameter of the function gives you the number of colliders it found, allowing you to loop through them:


private void RaycastNonAlloc()
{
    RaycastHit[] results = new RaycastHit[5];

    int numberHits = Physics.RaycastNonAlloc(transform.position, transform.up, results, Mathf.Infinity);

    for (int i = 0; i < numberHits; i++)
    {
        var hit = results[i];
        // Do actions
    }
}

RaycastHit

RaycastHit is a Unity structure that provides more information when a collider is hit. You can retrieve the distance, the normal, the transform of the hit collider, and the point of impact:

Consult Unity’s documentation for more information.

BoxCast

Boxcast allows you to cast a box along the ray:
See also BoxCastAll and BoxCastNonAlloc.


private void BoxCast()
{
    // Size / 2
    var extends = Vector3.one * 0.5f;
    var direction = new Vector3(0.7f, 0.7f);
    var rotation = Quaternion.Euler(Vector3.forward * 45f);
    var distance = 10f;

    if (Physics.BoxCast(transform.position, extends, direction, out RaycastHit rayCastHit, rotation, distance))
    {
        // Do actions with rayCastHit
    }
}

Unity BoxCast

SphereCast

SphereCast allows you to cast a sphere along the ray:
See also SphereCastAll and SphereCastNonAlloc.


private void SphereCast()
{
    float radius = 1f;
    var distance = 10f;
    var direction = transform.right;

    if (Physics.SphereCast(transform.position, radius, direction, out RaycastHit rayCastHit, distance))
    {
        // Do actions with rayCastHit
    }
}

Unity SphreCast

CapsuleCast

CapsuleCast allows you to cast a capsule in the specified direction. To create a capsule, you need to pass two points (Vector3) that define the two spheres and a float for their radius:
See also SphereCastAll and SphereCastNonAlloc.


private void CapsuleCast()
{
    // Draw a horizontal capsule at the center of the world
    float width = 4f;
    var point1 = -Vector3.right * width / 2f;
    var point2 = bottom + Vector3.right * width;

    float radius = 1f;

    if (Physics.CapsuleCast(transform.position + point1, transform.position + point2, radius, direction, out RaycastHit raycastHit, distance))
    {
        // Do actions with rayCastHit
    }
}

Unity CapsuleCast

Linecast

Linecast is a bit different because it no longer uses a direction. Instead, it uses two points to define a line. The function returns true if a collider intersects the line. It does not have All or NonAlloc methods:


private void Linecast()
{
    if (Physics.Linecast(transform.position, transform.position + Vector3.forward * 2f, out RaycastHit raycastHit))
    {
        // Do actions with rayCastHit
    }
}

OverlapBox

OverlapBox find colliders touching or enclosed by a specified box. You can also use OverlapBoxNonAlloc:


private void OverlapBox()
{
    var center = Vector3.zero;
    // Size / 2
    var extents = new Vector3(2.5f, 5f, 2.5f);
    // Rotate 25 around Z axis
    var rotation = Quaternion.Euler(Vector3.forward * 25f);

    Collider[] colliders = Physics.OverlapBox(center, extents, rotation);
}

Unity OverlapBox

OverlapSphere

OverlapSphere find colliders touching or enclosed by a specified sphere. You can also use OverlapSphereNonAlloc:


private void OverlapSphere()
{
    float radius = 1f;

    Collider[] colliders = Physics.OverlapSphere(Vector3.zero, radius);
}

Unity OverlapSphere

OverlapCapsule

OverlapCapsule find colliders touching or enclosed by a specified capsule. You can also use OverlapCapsuleNonAlloc:


private void OverlapCapsule()
{
    // Draw a horizontal capsule at the center of the world
    float width = 4f;
    var point1 = -Vector3.right * width / 2f;
    var point2 = bottom + Vector3.right * width;

    float radius = 1f;

    Collider[] colliders = Physics.OverlapCapsule(point1, point2, radius);
}

Unity OverlapCapsule

Raycast Collider

Collider.Raycast is very useful to know if a ray touches your collider regardless of obstacles. With this function, all other colliders are ignored except the collider itself:


private Collider _collider;

private void Awake()
{
    _collider = GetComponent();
}

private void ColliderRayCast()
{
    var ray = new Ray(Vector3.zero, Vector3.left);
    var distance = 10f;

    if (_collider.Raycast(ray, out RaycastHit raycastHit, distance))
    {
        // Do actions with rayCastHit
    }
}

Unity Collider Raycast

Raycast Plane

Plane.Raycast can be very useful for detecting clicks on a flat surface. Here’s a simpler example for better visualization:

This Unity structure defines a plane of infinite width, effectively dividing space into two halves. The “GetSide” method can determine whether a point is on the positive or negative side of the plane. A plane is defined by passing a normal (normalized direction) and a point through which the plane passes. In our case, “new Plane(Vector3.up, Vector3.zero);” makes the plane point upwards and pass through the center of our world, creating an unrotated plane passing through the point 0, 0, 0. (See image after the code)

During a raycast, the “enter” parameter indicates the distance between the ray’s origin and the hit point. For our example, we simply perform a raycast from the game object pointing downwards (relative to the game object):


private void PlaneCast()
{
    var plane = new Plane(Vector3.up, Vector3.zero);
    var ray = new Ray(transform.position, -transform.up);

    if (plane.Raycast(ray, out float enter))
    {
        // Do actions
    }
}

Unity Plane Raycast

The plane is just a visualization; the Plane structure does not display anything. You can also perform raycasts with NavMesh (NavMesh.Raycast), but this topic is extensive and not suitable for this article.

Leave a Reply

Your email address will not be published. Required fields are marked *