Comprobación del suelo con un rayo
Parte de la sección Física y jugabilidad del Journey de Unity de Coddy. Lección 37 de 71.
Un salto solo debería empezar desde el suelo. Standing on the Ground lo determinaba a partir de las normales de contacto, que se mantenían actualizadas mediante mensajes de colisión. Un rayo responde «¿estoy sobre algo?» en el acto, en cualquier momento: lánzalo en línea recta hacia abajo desde el centro, con una longitud un poco mayor que la distancia desde el centro hasta la parte inferior. Este jugador es una cápsula de 2 unidades de altura, así que su parte inferior está 1 unidad por debajo de su centro, y el rayo mide 1.1:
public float jumpForce = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
bool IsGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, 1.1f);
}El 0.1 adicional es un margen. Un cuerpo que está apoyado en el suelo puede quedar una pizca por encima o hundirse una pizca en él, así que un rayo de exactamente 1 de longitud no lo detecta en algunos fotogramas. Una longitud mucho mayor es incorrecta por el motivo opuesto: con 3, el jugador podría volver a saltar estando a 2 unidades del suelo, y si no tuviera longitud, el rayo siempre encontraría el suelo, así que cada pulsación provocaría un salto.
El rayo empieza dentro del propio colisionador del jugador, que los rayos omiten, así que nunca detecta al jugador. La tecla se lee en Update(), porque GetKeyDown solo es true durante un fotograma, y se puede añadir ahí mismo un impulso puntual, como en Saltar con un impulso.
Desafío
IntermedioHaz que la rana salte solo desde el suelo.
- Añade
bool IsGrounded(), que devuelvePhysics.Raycast(transform.position, Vector3.down, 0.85f): el radio de la rana, 0.75, más 0.1. - En
Update(), añade&& IsGrounded()alifde Space.
Pulsa «Jugar» y pulsa Space dos veces: la rana salta una vez. Después, pulsa «Comprobar».
Pruébalo tú mismo
using UnityEngine;
public class Hopper : MonoBehaviour
{
public float jumpForce = 6f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
}
Todas las lecciones de Física y jugabilidad
1Cuerpo rígido
Gravedad y masaEmpujar con AddForceSaltar con un impulsoFixedUpdate para físicaVelocidadCuerpos cinemáticosRepaso: plataforma de lanzamiento4Corrutinas
InvocarInvokeRepeating y CancelInvokeTu primera corrutinaBucles en corrutinasDetener corrutinasRepaso: cuenta regresiva10Proyecto: Escape de la arena
La arenaCazadores2Colisiones
OnCollisionEnter¿Qué golpeé?Romper al impactarDe pie sobre el sueloRebote y fricciónFormas de los collidersRepaso: muro destructible5Proyecto: Carrera de Monedas
La pelota rodanteMonedas para recoger3Disparadores
Colisionadores de tipo triggerOnTriggerEnterObjetos coleccionablesLas cajas guardan el restoZonas letalesEntrada y salidaRepaso: llave y puerta6Raycasts
Physics.RaycastRaycastHitComprobación del suelo con un rayoCapas y LayerMaskLínea de visiónOverlapSphere y SphereCastRepaso: cable trampa láserPractica por tu cuenta: Playground de Unity