Menu
CoddyTech

FixedUpdate per la fisica

Fa parte della sezione Fisica e gameplay del percorso Unity di Coddy. Lezione 4 di 63.

Unity sposta i corpi in intervalli di fisica fissi di 0.02 secondi (Time.fixedDeltaTime), 50 volte al secondo, indipendentemente dalla frequenza dei fotogrammi. FixedUpdate() viene eseguito subito prima di ogni intervallo. Update() viene eseguito una volta per ogni fotogramma disegnato, e questo può avvenire 30, 60 o 144 volte al secondo: a 144, la maggior parte dei fotogrammi non ha alcun intervallo di fisica e, su un computer lento, un fotogramma può contenerne due.

Ne conseguono due regole. Una forza aggiunta in Update() viene aggiunta una volta per fotogramma, quindi un computer più veloce spinge con più forza: le forze che agiscono nel tempo vanno inserite in FixedUpdate(). E GetKeyDown è true per un solo fotogramma; se quel fotogramma non ha un intervallo di fisica, FixedUpdate() non lo rileva e la pressione viene persa. Quindi rileva le pressioni in Update(), memorizzale in un bool e agisci su di esse in FixedUpdate(). Questa barca viene spinta da un vento costante e scatta lateralmente al clic:

private bool dashQueued;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        dashQueued = true;   // memorizza il clic
    }
}

void FixedUpdate()
{
    rb.AddForce(Vector3.forward * wind);   // una spinta costante, a ogni passo
    if (dashQueued)
    {
        rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
        dashQueued = false;   // un clic, uno scatto
    }
}

È importante azzerare il bool dopo averlo usato: se lasciato a true, la barca scatterebbe a ogni intervallo. Si potrebbe anche aggiungere un singolo impulso direttamente da Update(), come è stato fatto per il salto della rana; il bool mantiene tutte le spinte in un unico posto, accanto alle forze con cui interagisce. I tasti tenuti premuti (GetKey, GetAxis) descrivono uno stato anziché un istante, quindi FixedUpdate() può leggerli direttamente. All'interno di FixedUpdate(), Time.deltaTime restituisce il valore 0.02 dell'intervallo.

challenge icon

Sfida

Facile

La slitta sul lago ghiacciato esegue entrambe le sue operazioni nel metodo sbagliato. Le frecce la spingono in Update(), quindi viene spinta più forte sui computer più veloci. La barra spaziatrice la fa saltare con un impulso in FixedUpdate(), quindi alcune pressioni non producono alcun effetto.

  • Sposta la spinta delle frecce in FixedUpdate().
  • Leggi la barra spaziatrice in Update() in una bool chiamata hopPressed; in FixedUpdate(), fai saltare la slitta quando è impostata, poi cancellala.

Premi Play e prova entrambe le cose, poi Check.

Provalo tu

using UnityEngine;

public class Sled : MonoBehaviour
{
    public float push = 6f;
    public float hop = 5f;
    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.RightArrow))
        {
            rb.AddForce(Vector3.right * push);
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            rb.AddForce(Vector3.left * push);
        }
    }

    void FixedUpdate()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.AddForce(Vector3.up * hop, ForceMode.Impulse);
        }
    }
}
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 Fisica e gameplay