Menu
CoddyTech

Gravité manuelle

Fait partie de la section Créer de vrais jeux du Journey Unity de Coddy. Leçon 38 sur 56.

Un CharacterController ne tombe que si votre script le fait tomber, et une vraie chute s’accélère : la gravité ajoute environ 9.81 unités par seconde à la vitesse de chute chaque seconde. Le script conserve donc la vitesse verticale dans un champ, lui ajoute gravity * Time.deltaTime à chaque frame, puis s’en sert pour le déplacement dans le même Move que la marche :

public float gravity = -9.81f;
float verticalSpeed;

void Update()
{
    if (controller.isGrounded && verticalSpeed < 0f)
    {
        verticalSpeed = -2f;   // au sol : arrêter la chute, maintenir une légère poussée vers le bas
    }
    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 apparaît deux fois pour deux raisons : gravity * Time.deltaTime correspond à la vitesse gagnée pendant cette frame, et la vitesse multipliée par Time.deltaTime correspond à la distance parcourue pendant cette frame. La vitesse est un champ parce qu’elle doit persister d’une frame à l’autre ; une variable locale repartirait de 0 à chaque frame. En tombant depuis l’arrêt, le contrôleur atteint -4.9 unités par seconde après une demi-seconde et -9.81 après une seconde.

La réinitialisation est aussi importante que la chute. Au sol, Move arrête le contrôleur, mais rien n’arrête le champ : sans réinitialisation, sa valeur continue d’augmenter pendant que le joueur reste immobile, et le prochain pas dans le vide se fait à pleine vitesse. Elle est réinitialisée à un petit nombre négatif plutôt qu’à 0 afin que chaque Move continue d’exercer une pression vers le sol : à une fréquence d’images élevée, la poussée due à la gravité pendant une seule frame peut être plus courte que Min Move Distance ; Move ne fait alors rien et isGrounded devient false. isGrounded est lu avant Move ; il décrit donc le Move de la frame précédente.

challenge icon

Défi

Moyen

Le plongeur se tient au sommet d’une haute tour, et les flèches le font marcher (déjà écrit). Ajoute la gravité dans Diver.cs. L’Inspector définit gravity (-12) et maxFall (10), et le script possède le champ verticalSpeed.

  • À chaque image, verticalSpeed augmente de gravity par seconde, et le plongeur descend en fonction de cette valeur avec le même appel à Move que pour la marche.
  • L’air ralentit une longue chute : le plongeur ne tombe jamais plus vite que maxFall unités par seconde.
  • Lorsque le contrôleur est au sol et que verticalSpeed est inférieur à 0, définis verticalSpeed sur -1.

Appuie sur Play, marche jusqu’au bord de la tour, puis appuie sur Check.

Essayez vous-même

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é : réinitialiser verticalSpeed au sol, appliquer la gravité, limiter la vitesse de chute, puis la placer dans move.y

        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        controller.Move(move * Time.deltaTime);
    }
}
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 Créer de vrais jeux