Unity raycast presentation

Guide sur Raycast et Overlap dans Unity

Dans ce guide complet, nous plongeons dans les puissants outils de raycast et de superposition (overlap) dans Unity, offrant une exploration détaillée de leurs fonctionnalités et applications.

Table des matières

Paramètres communs

Chaque raycast partage des paramètres communs :

  • Direction : un vecteur définissant la direction du rayon.
  • Distance maximale : limite la longueur du rayon (Mathf.Infinity pour aucune limite).
  • LayerMask : détermine sur quelles couches le rayon sera appliqué (voir mon article : Maîtrise de LayerMask dans Unity).
  • QueryTriggerInteraction : restreint ou permet la possibilité de toucher les déclencheurs (trigger colliders).

Par défaut, chaque « Raycast » est fourni avec plusieurs méthodes :

  • Méthode de base (Raycast) : le rayon s’arrête dès qu’un collider est trouvé.
  • Méthode All (RaycastAll) : le rayon renvoie tous les colliders touchés.
  • Méthode NonAlloc (RaycastNonAlloc) : le rayon renvoie tous les colliders touchés, mais le tableau de résultats est passé directement en paramètre (buffer) pour de meilleures performances.

Raycast de base (Physics.Raycast) dans Unity

Pour utiliser le Raycast, vous pouvez fournir une position et une direction ou fournir directement un Ray. Voici un exemple :


using UnityEngine;

public class RaycastMonoBehaviour : MonoBehaviour
{
    private void FixedUpdate()
    {
        // Raycast depuis la position de l'objet de jeu vers le haut avec une distance infinie
        if (Physics.Raycast(transform.position, transform.up, out RaycastHit rayCastHit, Mathf.Infinity))
        {
            // Action avec rayCastHit
        }

        // Alternative avec un rayon
        var ray = new Ray(transform.position, transform.up);

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

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

Unity raycast

Raycast All

La méthode RaycastAll renvoie un tableau de RaycastHit :


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

    // Retourne un tableau de RaycastHit
    for (int i = 0; i < hits.Length; i++)
    {
        var hit = hits[i];
    }
}

Raycast NonAlloc

Pour utiliser RaycastNonAlloc, vous devez instancier un tableau non dynamique avec le nombre maximal de collisions que vous pouvez détecter. Le rayon s’arrête s’il n’y a plus de colliders ou si le tableau est plein. Le paramètre de sortie de la fonction vous donne le nombre de colliders trouvés, ce qui vous permet de les parcourir :


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];
        // Effectuez des actions
    }
}

RaycastHit

RaycastHit est une structure Unity qui fournit plus d’informations lorsque le rayon touche un collider. Vous pouvez récupérer la distance, la normale, la transformation du collider touché et le point d’impact. Consultez la documentation Unity pour plus d’informations.

BoxCast

BoxCast vous permet de cast une boîte le long du rayon :
Voir aussi BoxCastAll et BoxCastNonAlloc.


private void BoxCast()
{
    // Taille / 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))
    {
        // Effectuez des actions avec rayCastHit
    }
}

Unity BoxCast

SphereCast

SphereCast vous permet de cast une sphère le long du rayon :
Voir aussi SphereCastAll et SphereCastNonAlloc.


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

    if (Physics.SphereCast(transform.position, rayon, direction, out RaycastHit rayCastHit, distance))
    {
        // Effectuez des actions avec rayCastHit
    }
}

Unity SphereCast

CapsuleCast

CapsuleCast vous permet de cast une capsule dans la direction spécifiée. Pour créer une capsule, vous devez passer deux points (Vector3) qui définissent les deux sphères et un float pour leur rayon :
Voir aussi CapsuleCastAll et CapsuleCastNonAlloc.


private void CapsuleCast()
{
    // Dessinez une capsule horizontale au centre du monde
    float largeur = 4f;
    var point1 = -Vector3.right * largeur / 2f;
    var point2 = bottom + Vector3.right * largeur;

    float rayon = 1f;

    if (Physics.CapsuleCast(transform.position + point1, transform.position + point2, rayon, direction, out RaycastHit raycastHit, distance))
    {
        // Effectuez des actions avec rayCastHit
    }
}

Unity CapsuleCast

Linecast

Linecast est un peu différent car il n’utilise plus une direction. À la place, il utilise deux points pour définir une ligne. La fonction renvoie true si un collider intersecte la ligne. Elle n’a pas de méthodes All ou NonAlloc :


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

OverlapBox

OverlapBox trouve des colliders touchant ou enfermés dans une boîte spécifiée. Vous pouvez également utiliser OverlapBoxNonAlloc :


private void OverlapBox()
{
    var centre = Vector3.zero;
    // Taille / 2
    var dimensions = new Vector3(2.5f, 5f, 2.5f);
    // Faites tourner de 25 autour de l'axe Z
    var rotation = Quaternion.Euler(Vector3.forward * 25f);

    Collider[] colliders = Physics.OverlapBox(centre, dimensions, rotation);
}

Unity OverlapBox

OverlapSphere

OverlapSphere trouve des colliders touchant ou enfermés dans une sphère spécifiée. Vous pouvez également utiliser OverlapSphereNonAlloc :


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

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

Unity OverlapSphere

OverlapCapsule

OverlapCapsule trouve des colliders touchant ou enfermés dans une capsule spécifiée. Vous pouvez également utiliser OverlapCapsuleNonAlloc :


private void OverlapCapsule()
{
    // Dessinez une capsule horizontale au centre du monde
    float largeur = 4f;
    var point1 = -Vector3.right * largeur / 2f;
    var point2 = bottom + Vector3.right * largeur;

    float rayon = 1f;

    Collider[] colliders sont Physics.OverlapCapsule(point1, point2, rayon);
}

Unity OverlapCapsule

Raycast Collider

Collider.Raycast est très utile pour savoir si un rayon touche votre collider, quel que soit les obstacles. Avec cette fonction, tous les autres colliders sont ignorés sauf le collider lui-même :


private Collider _collider;

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

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

    if (_collider.Raycast(rayon, out RaycastHit raycastHit, distance))
    {
        // Effectuez des actions avec rayCastHit
    }
}

Unity Collider Raycast

Raycast Plane

Plane.Raycast peut être très utile pour détecter des clics sur une surface plate. Voici un exemple plus simple pour une meilleure visualisation :

Cette structure Unity définit un plan de largeur infinie, divisant efficacement l’espace en deux moitiés. La méthode « GetSide » peut déterminer si un point se trouve du côté positif ou négatif du plan. Un plan est défini en passant un vecteur normalisé (direction normalisée) et un point à travers lequel le plan passe. Dans notre cas, « new Plane(Vector3.up, Vector3.zero); » fait pointer le plan vers le haut et passe par le centre de notre monde, créant un plan sans rotation passant par le point 0, 0, 0. (Voir l’image après le code)

Lors d’un raycast, le paramètre « enter » indique la distance entre l’origine du rayon et le point d’impact. Pour notre exemple, nous effectuons simplement un raycast depuis le gameObject pointant vers le bas (par rapport au gameObject) :


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

    if (plan.Raycast(rayon, out float enter))
    {
        // Effectuez des actions
    }
}

Unity Plane Raycast

Le plan est simplement une visualisation ; la structure Plane n’affiche rien.

Vous pouvez également effectuer des raycasts avec NavMesh (NavMesh.Raycast), mais ce sujet est étendu et ne convient pas à cet article.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *