Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
We use cookies to ensure that we provide you with the best possible experience on our site.
Your essential source on Unity and web development
Your essential source on Unity and web development
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
Every raycast shares common parameters:
By default, each “Raycast” is provided with several methods:
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
}
}
}
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];
}
}
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 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 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
}
}
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
}
}
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
}
}
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 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);
}
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);
}
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);
}
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
}
}
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
}
}
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.