Menu
CoddyTech

Gravità manuale

Fa parte della sezione Creare veri giochi del percorso Unity di Coddy. Lezione 39 di 60.

Un CharacterController cade solo se lo script lo fa cadere, e una caduta reale accelera: la gravità aggiunge circa 9.81 unità al secondo alla velocità di caduta ogni secondo. Quindi lo script mantiene la velocità verticale in un campo, vi aggiunge gravity * Time.deltaTime a ogni frame e la usa per muoversi nello stesso Move della camminata:

public float gravity = -9.81f;
float verticalSpeed;

void Update()
{
    if (controller.isGrounded && verticalSpeed < 0f)
    {
        verticalSpeed = -2f;   // a terra: interrompi la caduta, mantieni una leggera spinta verso il basso
    }
    verticalSpeed += gravity * Time.deltaTime;

    Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
    move.y = verticalSpeed;
    controller.Move(move * Time.deltaTime);
}

Time.deltaTime compare due volte per due scopi: gravity * Time.deltaTime è la velocità guadagnata in questo frame, e la velocità moltiplicata per Time.deltaTime è la distanza percorsa in questo frame. La velocità è un campo perché deve durare da un frame all'altro; una variabile locale ripartirebbe da 0 a ogni frame. Cadendo da fermo, dopo mezzo secondo il controller raggiunge -4.9 unità al secondo e dopo un secondo -9.81.

Il ripristino è importante quanto la caduta. Sul pavimento Move ferma il controller, ma nulla ferma il campo: senza il ripristino continua ad aumentare mentre il giocatore è fermo, e il passo successivo oltre il bordo lo fa precipitare a velocità massima. Viene ripristinata a un piccolo numero negativo anziché a 0, così ogni Move continua a spingere verso il pavimento: con una frequenza dei frame elevata, la spinta della gravità di un singolo frame può essere inferiore a Min Move Distance, Move non fa nulla e isGrounded diventa false. isGrounded viene letto prima di Move, quindi descrive il Move dell'ultimo frame.

challenge icon

Sfida

Medio

Assegna la gravità al subacqueo, così la sua caduta accelera.

  1. All’inizio di Update(), quando controller.isGrounded e verticalSpeed < 0f, imposta verticalSpeed = -1f;.
  2. Somma gravity * Time.deltaTime al suo valore e mantienilo pari o superiore a -maxFall con Mathf.Max.
  3. Prima della riga controller.Move, imposta move.y = verticalSpeed;.

Premi «Gioca» e cammina giù dalla torre: la caduta accelera fino a 10 unità al secondo. Poi premi «Verifica».

Provalo tu

using UnityEngine;

public class Diver : MonoBehaviour
{
    public float speed = 4f;
    public float gravity = -12f;
    public float maxFall = 10f;

    CharacterController controller;
    float verticalSpeed;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        // Gravità: reimposta verticalSpeed quando si è a terra, aggiungi la gravità, limita la velocità di caduta e inserisci il risultato in move.y

        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        controller.Move(move * Time.deltaTime);
    }
}

Tutte le lezioni di Creare veri giochi

Esercitati da solo: Playground Unity