De pie sobre el suelo
Parte de la sección Física y jugabilidad del Journey de Unity de Coddy. Lección 11 de 71.
Todo contacto tiene una normal: una dirección de longitud 1, perpendicular a la superficie que tocaste y que apunta desde ella hacia tu objeto. collision.GetContact(0) es el primer punto de contacto, y su normal te indica qué lado tocaste. Al estar de pie sobre un suelo plano, es (0, 1, 0); contra una pared a tu derecha, es (-1, 0, 0); al golpearte la cabeza contra un techo, es (0, -1, 0).
Esta caja distingue los aterrizajes de los golpes laterales:
void OnCollisionEnter(Collision collision)
{
Vector3 normal = collision.GetContact(0).normal;
if (normal.y > 0.5f)
{
Debug.Log("Landed on " + collision.gameObject.name);
}
else
{
Debug.Log("Bumped the side of " + collision.gameObject.name);
}
}La prueba es normal.y > 0.5f en lugar de exactamente 1 para que las pendientes también cuenten como suelo: y es 0.5 en una pendiente de 60 grados, más empinada de lo que cualquiera puede subir caminando. Otros dos mensajes ayudan con cualquier cosa que dure: OnCollisionStay se ejecuta en cada paso de física mientras dura el contacto, y OnCollisionExit, una vez cuando termina. Al salir no hay puntos de contacto, ya que nada está tocando nada, así que no llames a GetContact en ese caso.
Desafío
FácilHaz que el jugador solo pueda saltar cuando esté sobre algo.
- Añade
private bool grounded;. EnOnCollisionStay, asígnale el valor true cuandocollision.GetContact(0).normal.y > 0.5f; enOnCollisionExit, asígnale el valor false. - En
FixedUpdate(), salta soloif (jumpPressed && grounded)y asignajumpPressed = false;después de eseif, para que se descarte una pulsación en el aire.
Pulsa «Jugar» y prueba a hacer un doble salto: la segunda pulsación no hace nada. Después, pulsa «Comprobar».
Pruébalo tú mismo
using UnityEngine;
public class Hopper : MonoBehaviour
{
public float speed = 4f;
public float jump = 6f;
private Rigidbody rb;
private bool jumpPressed;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
jumpPressed = true;
}
}
void FixedUpdate()
{
float h = Input.GetAxisRaw("Horizontal");
rb.linearVelocity = new Vector3(h * speed, rb.linearVelocity.y, 0);
if (jumpPressed)
{
rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
jumpPressed = false;
}
}
}
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 puertaPractica por tu cuenta: Playground de Unity