Gravité manuelle
Fait partie de la section Créer de vrais jeux du Journey Unity de Coddy. Leçon 39 sur 60.
Un CharacterController ne tombe que si ton 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, et se déplace en fonction de cette vitesse 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 rôles : 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, car 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 au bout d'une demi-seconde et -9.81 au bout d'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 la réinitialisation, sa valeur continue d'augmenter pendant que le joueur reste immobile, et le prochain pas dans le vide entraîne une chute à pleine vitesse. La vitesse 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 inférieure à 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.
Défi
MoyenDonne au plongeur une gravité pour que sa chute s’accélère.
- Au début de
Update(), lorsquecontroller.isGroundedet queverticalSpeed < 0f, définisverticalSpeed = -1f;. - Ajoute
gravity * Time.deltaTimeà cette valeur, et maintiens-la à-maxFallou au-dessus avecMathf.Max. - Avant la ligne
controller.Move, définismove.y = verticalSpeed;.
Appuie sur « Jouer » et marche jusqu’au bord de la tour : la chute s’accélère jusqu’à 10 unités par seconde. Puis clique sur « Vérifier ».
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, ajouter la gravité, limiter la chute, puis placer le résultat dans move.y
Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
controller.Move(move * Time.deltaTime);
}
}
Toutes les leçons de Créer de vrais jeux
1Texte à l’écran
Canvas et texteAfficher le scoreFormater les nombresUn compte à reboursRécapitulatif : compteur de vitesse4Scènes et niveaux
Charger une scèneRedémarrer le niveauNiveau suivantConserver entre les scènesRécapitulatif : sélection du niveau2Boutons et écrans
Boutons et onClickLambdasRelier les éléments dans l’InspectorActiver et désactiver les panneauxBarres de santéRécapitulatif : boutique d’améliorations5Sauvegarder avec PlayerPrefs
Enregistrer un nombreCharger avec une valeur par défautMeilleur scoreEnregistrer les paramètresRécapitulatif : les pièces à la banque8Contrôleur de personnage
CharacterController.MoveGravité manuelleSauterPousser des objetsAvancer dans la direction du regardRécapitulatif : double sautEntraînez-vous par vous-même : Playground Unity