Le Déplacement
Qu’est ce qu’un déplacement dans un jeu vidéo ?
Un mouvement est une force, une énergie, une direction que nous donnons à notre personnage. Pour effectuer un mouvement, nous avons besoin de définir quelques variables indispensables comme la vitesse et l’accélération.
La vitesse est tout simplement la valeur qui permet de savoir à quelle “vitesse” de marche le personnage va se déplacer dans son environnement.
L’accélération permet de savoir à quelle vitesse le joueur va passer de la vitesse 0 à la vitesse maximale.
Dans un environnement 3D, le joueur peut aller de l’avant ou reculer, se déplacer sur les côtés et même sauter. Il se déplacer sur 3 grands Axe principaux qui sont :
- L’axe X : se déplacer sur les côtés, de gauche à droite.
- L’axe Y : se déplacer de haut en bas. Par exemple effectuer un saut ou une chute.
- L’axe Z : se déplacer en avant ou reculer.
Sur Godot, pour pouvoir stocker notre mouvement ( nôtre direction ), nous avons besoin d’un Vector3. Un Vector3 prend en paramètres des valeurs X, Y, Z.
Vector3 direction = new Vector3(0,0,0);
Maintenant il nous suffit de savoir quel mouvement à fait l’utilisateur et d’appliquer une direction au joueur.
Si le joueur décide d’aller de l’avant alors nous ferons : direction += Transform.Basis.Z;
Basis permet de savoir dans quelle direction l’utilisateur a choisi d’aller en prenant en compte la rotation de la caméra.
Voici le code complet des directions possibles :
Vector3 direction = new Vector3(0,0,0);
if(Input.IsActionPressed("move_up"))
{
direction += Transform.Basis.Z;
}
if(Input.IsActionPressed("move_down"))
{
direction -= Transform.Basis.Z;
}
if(Input.IsActionPressed("move_left"))
{
direction += Transform.Basis.X;
}
if(Input.IsActionPressed("move_right"))
{
direction -= Transform.Basis.X;
}
Maintenant pour déplacer le joueur, il existe une variable dans godot que nous devons modifier à l’aide de notre variable direction.
La variable que nous allons modifier est la variable velocity. La vélocité est la direction multipliée par la vitesse du personnage.
Nous avons plusieurs paramètres indiquant la vitesse comme la variable vitesse ou encore acceleration.
velocity = direction * vitesse * acceleration;
Maintenant, pour déplacer le joueur, nous allons devoir indiquer à notre personnage à quelle vitesse il se déplace selon la direction choisie. Pour cela, il suffit d’utiliser la vélocité.
Velocity avec un grand “V” contient le déplacement et la vitesse du personnage dans le noeud CharacterBody3D. Il suffit juste de lui associer notre velocité calculée.
Velocity = velocity;
La fonction MoveAndSlide() permet de déplacer le personnage en fonction de la vélocité que nous avons calculer. La fonction gère également les collisions.
Il suffit juste de l’ajouter en dessous de la Velocity.
Voici le code du déplacement :
public override void _PhysicsProcess(double delta)
{
Vector3 direction = new Vector3(0, 0, 0);
if(Input.IsActionPressed("move_up"))
{
direction += Transform.Basis.Z;
}
if(Input.IsActionPressed("move_down"))
{
direction -= Transform.Basis.Z;
}
if(Input.IsActionPressed("move_left"))
{
direction += Transform.Basis.X;
}
if(Input.IsActionPressed("move_right"))
{
direction -= Transform.Basis.X;
}
// Permet d'avoir la même vitesse même si on appuie sur deux directions
direction = direction.Normalized();
Velocity = velocity;
MoveAndSlide();
}
Le saut du personnage
Maintenant nous allons apprendre à faire sauter notre joueur.
Nous allons créer une variable qui contiendra la puissance du saut.
float jumpForce = 20f;
Nous avons appris à nous déplacer sur les axes X et Z pour aller en avant, en arrière, à gauche et à droite. Maintenant je veux que mon personnage puisse sauter. Pour cela nous devons modifier la valeur sur l’axe Y.
Pour rappel, la variable qui fait réellement déplacer notre personnage est la variable Velocity. Cette variable est de type Vector3 et contient les 3 grands Axe X, Y et Z.
Nous allons créer une variable qui gérera seulement l’axe Y de Velocity.
float yVelocity;
Pour sauter il faut d’abord savoir si on est sur le sol ou pas. Pour cela Godot à une fonction booléenne IsOnFloor(). Si le joueur est bien sur le sol, la fonction renvoie True sinon False.
If(Input.IsActionPressed(“jump”) && IsOnFloor())
{
yVelocity = jumpForce
}
Apprendre à tomber
Maintenant que nous savons sauter, il faut apprendre à retomber sur notre niveau.
Pour cela, nous allons créer une gravité.
float gravity = 1f;
Si le joueur à sauter donc si il n’est pas sur le sol , yVelocity -= gravity;
If(IsOnFloor() == False)
{
yVelocity -= gravity;
}
Maintenant avec un code mieux optimisé :
if(IsOnFloor())
{
yVelocity = -0.01f; // Pas besoin d'être attiré au sol car le personnage est déjà sur le sol
}
else()
{
yVelocity = Mathf.Clamp(yVelocity - gravity, -maxTerminalVelocity, maxTerminalVelocity);
}
maxTerminalVelocity contient la valeur maximum ou minimum que le joueur pourra atteindre.
Il nous reste à ajouter yVelocity à velocity.
velocity.Y = yVelocity;
Velocity = velocity;
MoveAndSlide();
Voici le code complet pour la gravité :
// Gravité
if(IsOnFloor())
{
yVelocity = -0.01f; // Pas besoin d'être attiré au sol car le personnage est déjà sur le sol
}
else
{
yVelocity = Mathf.Clamp(yVelocity - gravity, -maxTerminalVelocity, maxTerminalVelocity);
animationPlayer.Play("fall");
}
// Saut
if(Input.IsActionJustPressed("jump") && IsOnFloor())
{
yVelocity = jumpForce;
}
velocity.Y = yVelocity;
Velocity = velocity;
MoveAndSlide();
Gérer mouvement de la souris
Nous voulons que la caméra suive les mouvements de la souris. Pour cela nous allons utiliser la fonction prédéfini dans Godot _Input(). Cette fonction permet de gérer tout type d’input comme le clavier, une manette, une souris, etc.
Voici le code complet :
// Detecte les input automatiquement
public override void _Input(InputEvent @event)
{
if(@event is InputEventMouseMotion motionEvent)
{
// On modifie la rotation sur l'axe Y du noeud principal
// Le personnage et la camera vont pivoter de gauche à droite
Vector3 rotDeg = RotationDegrees;
rotDeg.Y -= motionEvent.Relative.X * mouseSensivity;
RotationDegrees = rotDeg;
// On pivote le noeud Camera sur son Axe X
// Donc de haut en bas
rotDeg = camera.RotationDegrees;
rotDeg.X -= motionEvent.Relative.Y * -mouseSensivity;
rotDeg.X = Mathf.Clamp(rotDeg.X, minPitch, maxPitch);
camera.RotationDegrees = rotDeg;
}
}
Je vais vous expliquer ligne par ligne simplement le code.
if(@event is InputEventMouseMotion motionEvent) -> Si l’event qui se produit est un mouvement de souris
Vector3 rotDeg = RotationDegrees; -> RotationDegrees est de type Vector3. Permet de gérer la rotation sur tous les Axes.
rotDeg.Y -= motionEvent.Relative.X * mouseSensivity; -> Pour pouvoir bouger la souris de gauche à droite, il faut pivoter l’Axe Y. motionEvent.Relative.X équivaut à la position de la souris sur l’axe X (de gauche à droite). mouseSensivity est la sensibilité de la souris que nous pouvons ajuster.
Pour appliquer les modifications : RotationDegrees = rotDeg;
Maintenant pour pouvoir bouger la tête de haut en bas, il faut seulement appliquer une rotation sur la caméra et non sur le joueur comme nous l’avons fait précédemment.
donc rotDeg = camera.RotationDegrees; -> Cette fois ci c’est bien la caméra que nous déplaçons et non plus le joueur
rotDeg.X -= motionEvent.Relative.Y * -mouseSensivity; -> On applique la rotation sur l’axe X pour pouvoir déplacer la caméra de haut en bas.
rotDeg.X = Mathf.Clamp(rotDeg.X, minPitch, maxPitch); -> Mathf.Clamp() permet de bloquer sur un intervalle donné les limites de rotations de la caméra. Grâce à cela, la caméra nous pourra pas faire de 360 en boucle en montant ou descendant la souris.
camera.RotationDegrees = rotDeg; -> On applique la rotation voulu au vecteur qui gère les rotations du noeud camera cameraPivot.RotationDegrees.