Qué es un raycast#
Un raycast lanza un rayo invisible desde un punto en una dirección y te dice qué collider golpea primero y dónde. Es una de las herramientas más versátiles: disparos instantáneos, saber si el jugador pisa el suelo, detectar qué mira, clics en el mundo 3D...
El raycast básico#
using UnityEngine;
public class Disparo : MonoBehaviour
{
[SerializeField] private Camera camara;
[SerializeField] private float alcance = 100f;
void Update()
{
if (Input.GetMouseButtonDown(0))
Disparar();
}
void Disparar()
{
Ray rayo = new Ray(camara.transform.position, camara.transform.forward);
if (Physics.Raycast(rayo, out RaycastHit hit, alcance))
{
Debug.Log("He golpeado: " + hit.collider.name);
Debug.Log("En el punto: " + hit.point);
// ¿Lo golpeado tiene un componente Enemigo?
if (hit.collider.TryGetComponent<Enemigo>(out var enemigo))
enemigo.RecibirDaño(25);
}
}
}Physics.Raycast devuelve true/false (si golpeó algo) y rellena hit con la información del impacto.
Qué te da el RaycastHit#
| Campo | Contiene |
|---|---|
hit.collider | El collider golpeado |
hit.point | El punto exacto del impacto (mundo) |
hit.normal | La normal de la superficie (para orientar efectos) |
hit.distance | Distancia desde el origen |
hit.transform | El Transform del objeto golpeado |
hit.normal te dice hacia dónde "mira" la superficie golpeada. Instanciar una marca de bala con Quaternion.LookRotation(hit.normal) la pega perfectamente pegada a la pared, en cualquier ángulo.
Filtrar con LayerMask#
Sin filtro, el rayo golpea lo primero que encuentre, incluido a ti mismo. Usa un LayerMask para mirar solo ciertas capas:
[SerializeField] private LayerMask capas;
// El 4.º parámetro limita a esas capas
if (Physics.Raycast(origen, direccion, out RaycastHit hit, 50f, capas))
Debug.Log("Golpe filtrado: " + hit.collider.name);Ver Tags y Layers para entender los LayerMask.
Variantes útiles#
| Método | Para qué |
|---|---|
Physics.Raycast | Primer impacto en línea |
Physics.RaycastAll | Todos los impactos en la línea (devuelve array) |
Physics.SphereCast | Como un raycast pero con grosor (una esfera que viaja) |
Physics.OverlapSphere | Todo lo que hay dentro de una esfera (radio de explosión) |
Physics.Linecast | Rayo entre dos puntos concretos |
// ¿Hay línea de visión despejada entre el enemigo y el jugador?
bool veAlJugador = !Physics.Linecast(enemigo.position, jugador.position, obstaculos);Raycast en 2D#
En 2D se usa Physics2D.Raycast, que devuelve directamente el hit (no usa out):
RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, 1f, capaSuelo);
if (hit.collider != null)
Debug.Log("Suelo detectado: " + hit.collider.name);Depurar el rayo#
No ves el rayo por defecto. Dibújalo para entender qué pasa:
Debug.DrawRay(origen, direccion * alcance, Color.red); // visible en SceneErrores frecuentes#
- Que el rayo se golpee a sí mismo por no usar
LayerMask. - Olvidar que el rayo solo detecta colliders (un objeto sin collider es invisible al raycast).
- Confundir el orden de parámetros (distancia vs LayerMask).
- Lanzar muchos raycasts por frame sin necesidad (tiene coste; mide si abusas).
- En 2D, comprobar el
boolen vez dehit.collider != null.
Ponte a prueba#
Resumen#
Un raycast lanza un rayo y te dice qué collider golpea y dónde (RaycastHit: collider, punto, normal, distancia). Filtra con LayerMask para no golpearte a ti mismo, usa variantes como SphereCast o OverlapSphere según el caso, y recuerda Physics2D.Raycast en 2D. Solo detecta objetos con collider.