Menu
CoddyTech

FixedUpdate pour la physique

Fait partie de la section Physique et gameplay du Journey Unity de Coddy. Leçon 4 sur 63.

Unity déplace les corps par pas de physique fixes de 0.02 seconde (Time.fixedDeltaTime), 50 fois par seconde, quel que soit le taux d’images. FixedUpdate() s’exécute juste avant chaque pas. Update() s’exécute une fois par image affichée, soit 30, 60 ou 144 fois par seconde : à 144, la plupart des images ne comportent aucun pas de physique, et sur un ordinateur lent, une image peut en contenir deux.

Deux règles en découlent. Une force ajoutée dans Update() l’est une fois par image, donc un ordinateur plus rapide pousse plus fort : les forces qui agissent dans le temps vont dans FixedUpdate(). Et GetKeyDown n’est vrai que pendant une seule image ; si cette image ne comporte aucun pas de physique, FixedUpdate() ne le détecte jamais et la pression de la touche est perdue. Il faut donc lire les pressions dans Update(), les mémoriser dans un bool, puis agir en conséquence dans FixedUpdate(). Ce bateau est poussé par un vent constant et fait une embardée latérale au clic :

private bool dashQueued;

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        dashQueued = true;   // mémoriser le clic
    }
}

void FixedUpdate()
{
    rb.AddForce(Vector3.forward * wind);   // une poussée constante, à chaque étape
    if (dashQueued)
    {
        rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
        dashQueued = false;   // un clic, une ruée
    }
}

Il est important de remettre le booléen à zéro après l’avoir utilisé : s’il restait à true, le bateau ferait une embardée à chaque pas. Une impulsion unique pourrait aussi être ajoutée directement depuis Update(), comme l’a été le saut de la grenouille ; le booléen permet de regrouper toutes les poussées au même endroit, avec les forces qui agissent de concert. Les touches maintenues (GetKey, GetAxis) décrivent un état plutôt qu’un instant, donc FixedUpdate() peut les lire directement. Dans FixedUpdate(), Time.deltaTime renvoie la durée du pas, soit 0.02.

challenge icon

Défi

Facile

Le traîneau sur le lac gelé effectue ses deux actions dans la mauvaise méthode. Les flèches le poussent dans Update(), donc il est poussé plus fort sur les ordinateurs plus rapides. La barre d’espace le fait sauter avec une impulsion dans FixedUpdate(), donc certaines pressions ne font rien.

  • Déplace le déplacement par les flèches dans FixedUpdate().
  • Lis la barre d’espace dans Update() dans un bool nommé hopPressed ; dans FixedUpdate(), fais-le sauter si cette variable est définie, puis réinitialise-la.

Clique sur Play et essaie les deux, puis clique sur Check.

Essayez vous-même

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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Physique et gameplay