Controllo del terreno con un Ray
Fa parte della sezione Fisica e gameplay del percorso Unity di Coddy. Lezione 37 di 71.
Un salto dovrebbe iniziare solo da terra. La soluzione Standing on the Ground lo determinava usando le normali di contatto, mantenute aggiornate dai messaggi di collisione. Un raggio risponde sul momento, in qualsiasi istante, alla domanda «sto poggiando su qualcosa?»: proiettalo dritto verso il basso dal centro, con una lunghezza leggermente superiore alla distanza dal centro al fondo. Questo giocatore è una capsula alta 2 unità, quindi il fondo si trova 1 unità sotto il centro e il raggio è lungo 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);
}Lo 0.1 in più è un margine. Un corpo appoggiato sul pavimento può trovarsi appena sopra di esso o penetrarvi appena, quindi un raggio lungo esattamente 1 a volte non rileva il pavimento. Una lunghezza molto maggiore è sbagliata nella direzione opposta: con 3, il giocatore potrebbe saltare di nuovo quando si trova a 2 unità da terra; senza alcuna lunghezza, invece, il raggio trova sempre il pavimento, quindi ogni pressione avvia un salto.
Il raggio parte dall'interno del collider del giocatore, che i raggi ignorano, quindi non rileva mai il giocatore. Il tasto viene letto in Update(), perché GetKeyDown è vero per un solo fotogramma, e un impulso singolo può essere aggiunto proprio lì, come in Jump with an Impulse.
Sfida
MedioFai saltare la rana solo da terra.
- Aggiungi
bool IsGrounded()che restituiscePhysics.Raycast(transform.position, Vector3.down, 0.85f): il raggio della rana, 0.75, più 0.1. - In
Update(), aggiungi&& IsGrounded()all’ifrelativo alla barra spaziatrice.
Premi «Gioca» e premi due volte la barra spaziatrice: la rana salta una volta. Poi premi «Verifica».
Provalo tu
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);
}
}
}
Tutte le lezioni di Fisica e gameplay
1Corpo rigido
Gravità e massaSpingi con AddForceSalta con un impulsoFixedUpdate per la fisicaVelocitàCorpi cinematiciRiepilogo: piattaforma di lancio4Coroutine
InvokeInvokeRepeating, CancelInvokeLa tua prima coroutineCicli nelle coroutineInterrompere le coroutineRiepilogo: conto alla rovescia7Rotazione
Angoli di EuleroQuaternioniGuarda nella direzione in cui ti muoviRuota in modo fluidoRiepilogo: Torretta10Progetto: Fuga dall'arena
L'arenaCacciatori2Collisioni
OnCollisionEnterCosa ho colpito?Rompersi all'impattoRestare a terraRimbalzo e attritoForme dei ColliderRiepilogo: muro distruttibile5Progetto: Corsa alle monete
La palla rotolanteMonete da raccogliereEsercitati da solo: Playground Unity