Page 1 sur 1

Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 17:41
par Pandolphe
Bonjour bonjour,
Je suis en train de coder un jeu de plateforme 2d avec Unity en C#, et j'en suis au saut du personnage. Voici le bout de code concerné :

Code : Tout sélectionner

    void Saut()
    {
        if (Input.GetKey("up"))
        {
            directionY = saut * Time.deltaTime;
            masse.velocity = new Vector2(directionY, masse.velocity.y);
        }
    }
Quand j'appuie sur la flèche du haut, mon personnage se dirige vers la droite, ce qui signifie que mon conditionnel est juste.
Auriez-vous la solution à mon problème ?
Merci beaucoup :)

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 17:51
par Max
Bonjour,
Pandolphe a écrit :
10 Avr 2021 17:41
Quand j'appuie sur la flèche du haut, mon personnage se dirige vers la droite
Oui, ce qui parait à priori normal vu que tu modifies la composante 'X' de sa vélocité. Si tu veux le faire aller vers le haut, c'est surtout sur la composante Y qui faut jouer, d'autant que ta valeur s'appelle visiblement directionY.

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 18:12
par Pandolphe
Merci de ta réponse,
j'ai modifié ce qui me paraissait être ce qu'il fallait modifier, et je me retrouve avec le même résultat.
Voici mon nouveau code :

Code : Tout sélectionner

    void Saut()
    {
        if (Input.GetKey("up"))
        {
            directionY = saut * Time.deltaTime;
            masse.velocity = new Vector2(directionY, masse.velocity.x);
        }
    }
Est-ce que c'était bien cela qu'il fallait changer ? Si non, quoi ?

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 18:18
par jmhoubre
En supposant que ton joueur soit nommé masse, tu définis sa vélocité par un Vector2(x, y). Pour modifier cette vélocité vers le haut, il faut donc mettre directionY dans la seconde coordonnée. Quelque chose comme :

Code : Tout sélectionner

masse.velocity = new Vector2(masse.velocity.x, directionY);
Toutefois, pour un saut, il est généralement plus simple d'utiliser la physique avec Addforce().

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 18:22
par Pandolphe
J'ai changé cela et effectivement, tant que je laisse ma touche appuyée, mon personnage monte, et je peux aussi sauter quand je suis en l'air. Peux-tu s'il te plait m'expliquer comment utiliser AddForce() s'il te plait ?

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 18:50
par jmhoubre
J'ai cherché ta présentation, que je n'ai pas trouvé. Tu as quel niveau (c'est pour adapter mes explications) ?

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 19:09
par Pandolphe
j'ai commencé aujourd'hui

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 20:24
par jmhoubre
1. Introduction
Dans Unity, il y a plusieurs façons de gérer le mouvement :
  • En manipulant le transform du gameObject, par exemple le code ci-dessous va mouvoir le gameObject d'une unité sur l'axe X :

    Code : Tout sélectionner

    transform.position = new Vector3(transform.position.x + 1, transform.position.y, transform.position.z);
    
  • En modifiant la vélocité de l'objet, comme tu l'as fait.
  • En laissant le moteur physique s'en occuper, celle que je vais t'expliquer rapidement.
En gros, le moteur physique va calculer tous les mouvements en tenant compte des forces qui sont appliquées aux objets et des collision entre ces objets.

Dans une scène vide (caméra + lumière), place un simple cube 3D. Lance le jeu : il ne se passe rien. Sur ce même cube, ajoute (Add Component) un composant RigidBody (attention pas celui prévu pour la 2D), et lance le jeu. Cette fois, le cube tombe. En ajoutant le composant Rigidbody, tu as indiqué à Unity (à la partie moteur physique) d'appliquer au cube les lois de la physique, et Unity applique au cube la pesanteur, qui est une force exercée vers le bas.

Ouvre le composant Rigidbody, outre sa masse, il y a un booléen UseGravity qui est coché. Décoche la case, relance le jeu : le cube ne tombe plus.

Dans la scène, place un plane (GameObject > 3D Object > Plane). Modifie position.y du cube de façon à ce que le cube soit au-dessus du plane. Lance le jeu : le cube est arrêté par le plane.

Sur le plane, repère le composant Mesh Collider, et désactive-le en décochant sa case. Lance le jeu : le cube tombe et traverse le plane.
De manière très simplifiée :
  • pour être pris en compte par la physique, un gameObject doit avoir un Rigidbody.
  • pour interagir entre eux (collisions, ...), les gameObjects doivent avoir des Colliders.

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 20:40
par jmhoubre
2. Les forces
A partir du moment où un gameObject a un Rigidbody, on a accès aux méthodes et propriétés de ce composant, en particulier AddForce.

Il "suffit" donc d'appliquer une force à une objet, et laisser Unity s'occuper du reste (enfin c'est l'idée). Crée un script "JumpingCube" et attache le au cube précédent. Copie ce code dans le script :

Code : Tout sélectionner

using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class JumpingCube : MonoBehaviour
{
    // La valeur de la force à appliquer au gameObject.
    public float jumpForce = 200f;

    // Le rigidbody du gameObject.
    Rigidbody rigidBody;

    private void Awake ()
    {
        // Renseigne la référence.
        rigidBody = GetComponent<Rigidbody> ();
    }

    private void FixedUpdate ()
    {
        // Applique la force quand on appuie sur la barre d'espace.
        if (Input.GetKeyDown (KeyCode.Space))
        {
            rigidBody.AddForce (Vector3.up * jumpForce);
        }
    }
}
Le cube saute quand tu tapes la barre d'espace, et applique une force vers le haut de valeur jumpForce. La gravité fait descendre le cube jusqu'au plane.

Re: Coder le saut (jeu de plateforme)

Publié : 10 Avr 2021 20:54
par jmhoubre
3. Compléments
Voici quelques explications supplémentaires :
  • [RequireComponent(typeof(Rigidbody))] : impose la présence d'un Rigidbody sur le gameObject auquel est attaché le script. Cela évite de l'oublier et de générer des erreurs.
  • public float jumpForce = 200f; La variable est publique, ainsi elle apparait dans l'inspecteur quand le cube est sélectionné, on peut ainsi la modifier pendant le jeu. Note que la valeur de la force est à adapter selon la masse du cube. Avec une masse de 10 et une jumpForce à 200, le cube ne décolle pas !
  • rigidBody = GetComponent<Rigidbody> (); il faut indiquer à Unity quel est le composant sur lequel on veut agir. On peut écrire dans la méthode Update () GetComponent<Rigidbody>(). AddForce(...), mais ce n'est pas une bonne pratique, car GetComponent prend des ressources et l'exécuter des dizaines, voir des centaines de fois par seconde n'a pas de sens. Il est recommandé de mettre en cache cette valeur : on déclare une variable du bon type (ici Rigidbody rigidBody;), puis on renseigne cette valeur dans la fonction Awake ou Start, qui s'exécutent une fois au début du jeu.
  • Pour appliquer la force, AddForce attend soit un Vector3, soit 3 float. Le script utilise la 1ère manière, on peut aussi écrire AddForce (0f, jumpForce, 0f).
  • A noter que les calculs liés à la physique sont fait dans la méthode FixedUpdate (). Toutefois, il est recommandé de récupérer les inputs du joueur dans la fonction Update () (pour le saut en particulier, il peut arriver qu'Unity loupe des frappes de touche). On peut par exemple utiliser le code ci-dessous, qui utilise un boolean pour communiquer entre les deux méthodes.

Code : Tout sélectionner

using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class JumpingCube : MonoBehaviour
{
    // La valeur de la force à appliquer au gameObject.
    public float jumpForce = 200f;

    // Le rigidbody du gameObject.
    private Rigidbody rigidBody;

    private bool isJumping = false;

    private void Awake ()
    {
        // Renseigne la référence.
        rigidBody = GetComponent<Rigidbody> ();
    }

    private void Update ()
    {
        // Détection du saut.
        if (Input.GetKeyDown (KeyCode.Space))
        {
            isJumping = true;
        }
    }

    private void FixedUpdate ()
    {
        // Action de saut.
        if (isJumping)
        {
            rigidBody.AddForce (Vector3.up * jumpForce);
            isJumping = false;
        }
    }
}