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.
Défi
FacileLe 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 unboolnomméhopPressed; dansFixedUpdate(), 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);
}
}
}
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
1Corps rigide
Gravité et massePousser avec AddForceSauter avec une impulsionFixedUpdate pour la physiqueVitesseCorps cinématiquesRécapitulatif : plateforme de lancement4Coroutines
InvoquerInvokeRepeating, CancelInvokeVotre première coroutineBoucles dans les coroutinesArrêter les coroutinesRécapitulatif : compte à rebours2Collisions
OnCollisionEnterQu’est-ce que j’ai touché ?Se briser à l’impactRester au solRebond et frictionFormes des collidersRécapitulatif : mur destructible5Projet : Course aux pièces
La balle roulanteDes pièces à ramasser