Menu
CoddyTech

Gravità manuale

Fa parte della sezione Creare veri giochi del percorso Unity di Coddy. Lezione 38 di 56.

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, le aggiunge gravity * Time.deltaTime a ogni frame e si sposta in base a essa nella stessa 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 funzioni: gravity * Time.deltaTime è la velocità acquisita in questo frame, e la velocità moltiplicata per Time.deltaTime è la distanza percorsa in questo frame. La velocità è un campo perché deve persistere da un frame all'altro; una variabile locale ripartirebbe da 0 a ogni frame. Cadendo da fermo, dopo mezzo secondo il controller raggiunge una velocità di -4.9 unità al secondo, e -9.81 dopo un secondo.

Il ripristino è importante tanto quanto la caduta. Sul pavimento, Move ferma il controller, ma nulla ferma il campo: senza il ripristino continua a crescere mentre il giocatore è fermo, e al successivo passo oltre il bordo la caduta avviene alla massima velocità. Viene ripristinato a un numero negativo piccolo invece che a 0, così ogni Move continua a spingere contro 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 del frame precedente.

challenge icon

Sfida

Medio

Il subacqueo si trova in cima a una torre alta e le frecce lo spostano (già scritto). Aggiungigli la gravità in Diver.cs. Nell'Inspector imposta gravity (-12) e maxFall (10); lo script ha il campo verticalSpeed.

  • A ogni frame, verticalSpeed aumenta di gravity al secondo e il subacqueo si sposta verso il basso dello stesso valore nella stessa chiamata a Move usata per camminare.
  • L'aria rallenta una caduta lunga: il subacqueo non cade mai più velocemente di maxFall unità al secondo.
  • Quando il controller è a terra e verticalSpeed è minore di 0, imposta verticalSpeed su -1.

Premi Play, cammina giù dalla torre, poi premi Check.

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 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);
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Creare veri giochi