[RESOLU][DB - AL] Saut en avant (2.5D)

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [DB - AL] Saut en avant (2.5D)

Message par djulio74 » 05 Juin 2020 12:25

Alors pourquoi rajouter un isGrounded alors qu'il est déjà très bien géré dans le contrôler ?
Pour déplacer ton perso, si tu a un controler, tu ne devrais que utiliser du controler.Move, que ce soit pour le déplacement comme pour le saut.
Pour le saut il faut définir un vecteur avec du x et du y.
Je te montrer ça ce soir

Édit : poste nous ton ( ou tes) scripts complet définissant le déplacement du personnage, que je ( ou un autre) puisse te faire une réponse cohérente avec ce que tu as déjà mis en place ( utiliser les même Input, même syntaxe.. Etc)

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] Saut en avant (2.5D)

Message par Derek82 » 05 Juin 2020 13:00

J'ai suivi un tutoriel qui procédait comme ça, pour permettre de choisir ce sur quoi le personnage peut marcher (en sélectionnant un calque "ground" par exemple).
Dans mon exemple, puisque isGrounded est inclus dans le CharacterController, c'est vrai que c'est peut-être redondant.
Je peux optimiser le code, le simplifier en rassemblant les déplacements au sol (marche, course, marche accroupi et déclenchement du saut sur place et déclenchement du saut en longueur) sous une seule condition "isGrounded" à terme je suppose.

mais à moins que isGrounded du CharacterController entre en conflit avec le isGrounded rajouté qui va chercher un calque et utiliser un objet "ground checker" placer au niveau des pieds du personnage, je trouvais ça secondaire.

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] Saut en avant (2.5D)

Message par Derek82 » 05 Juin 2020 16:03

Pour l'instant ce qui marche le mieux c'est encore ce petit bout de code pour le saut en avant :

Code : Tout sélectionner

private Vector3 direction;
public float LongueurSaut = 60;
public float HauteurSautEnAvant = 10;

Code : Tout sélectionner

   // Sauter en avant
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            //direction.y = HauteurSautEnAvant;
            direction.x = LongueurSaut;
            //monAnim.SetTrigger("ConditionSautEnAvantTrigger");
            monAnim.SetFloat("ConditionSautEnAvantFloat", 1);
        }

        else if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            //monAnim.ResetTrigger("ConditionSautEnAvantTrigger");
            monAnim.SetFloat("ConditionSautEnAvantFloat", 0);
Quand j'appuie sur Shift gauche, le personnage se déplace de la longueur souhaitée, c'est déjà ça...
mais
1 - j'ai dû désactiver le paramètre "direction.y = HauteurSautEnAvant;" pour l'instant car du coup, le personnage n'est plus "isGrounded" et ça entre en conflit avec le code pour le saut sur place qui repose sur isGrounded aussi.

2 - pour l'instant le déplacement se fait dans un sens, vers la droite, y compris quand le personnage est orienté vers la gauche. mais je verrais ça plus tard peut etre...

Bon pour l'instant je me concentre surtout sur le point 3 :

3 - j'aimerai que le déplacement sur X se fasse progressivement.
je suppose qu'il faut introduire "* Time.deltaTime" quelque part mais je ne vois pas la logique

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] Saut en avant (2.5D)

Message par Derek82 » 05 Juin 2020 16:34

Ah je n'avais pas vu ton EDIT djulio64 :
Édit : poste nous ton ( ou tes) scripts complet définissant le déplacement du personnage, que je ( ou un autre) puisse te faire une réponse cohérente avec ce que tu as déjà mis en place ( utiliser les même Input, même syntaxe.. Etc)

Entendu, merci !
Voici le code que j'ai ajouté à mon Joueur, en plus du Character controller, d'un Rigidbody (redondant en apparence avec celui compris dans le Controller, mais d'après un tuto, ça peut avoir son interet pour les collisions)

il y a derrière des "//" quelques tentatives et commentaires qui trainent, comme j'essaie pas mal de choses à tâtons.
J'espère que ce n'est pas trop le bazar ! :triste1:

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class Script_Controles_V2 : MonoBehaviour
{
    // Historique : sauvegardé dans les archives en tant que Script_Controles_V2.1

    public CharacterController controller;
    private Vector3 direction;
    public GameObject AnimatorCible;

    // Se Retourner 1/3
    bool SeRetourner;
 
    // Vitesse de marche et course
    public float vitesseMarche = 5;
    public float vitesseCourse = 10;

    // Paramètres "Saut en avant
    public float LongueurSaut = 60;
    public float HauteurSautEnAvant = 10;

    // Paramètres "Saut sur place"
    public float HauteurSaut = 6;
    public float gravity = -45;
    public Transform groundCheck;
    public float rayonCheck;
    public LayerMask groundLayer;


   
    private Animator monAnim;
    private Rigidbody monRB;

    // ------------------------- //



    void Awake()
    {
        monAnim = AnimatorCible.GetComponent<Animator>();
        monRB = GetComponent<Rigidbody>();

    }


    void Start()
    {
        SeRetourner = true;

    }



    void Update()
    {
        controller.Move(direction * Time.deltaTime);


        // Marcher
        float marche = Input.GetAxis("Horizontal");
        monAnim.SetFloat("ConditionMarcher", Mathf.Abs(marche));


        // Courir
        float courir = Input.GetAxisRaw("Fire3");
        monAnim.SetFloat("ConditionCourir", courir);

        // if (courir > 0 && grounded)  ??
        if (courir > 0)
        {
            direction.x = marche * vitesseCourse;
        }

        else
        {
            direction.x = marche * vitesseMarche;
        }

        // Sauter en avant
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            //direction.y = HauteurSautEnAvant;
            direction.x = LongueurSaut;
            //monAnim.SetTrigger("ConditionSautEnAvantTrigger");
            monAnim.SetFloat("ConditionSautEnAvantFloat", 1);
        }

        else if (Input.GetKeyUp(KeyCode.LeftShift))
        {
            //monAnim.ResetTrigger("ConditionSautEnAvantTrigger");
            monAnim.SetFloat("ConditionSautEnAvantFloat", 0);
        }



        // Sauter
        bool isGrounded = Physics.CheckSphere(groundCheck.position, rayonCheck, groundLayer);
        monAnim.SetBool("ToucheLeSol", isGrounded);
        direction.y += gravity * Time.deltaTime;

        if (isGrounded)
        {
            
            if (Input.GetButtonDown("Jump"))
            {
                direction.y = HauteurSaut;
            }


        }



        // s'accroupir        
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            monAnim.SetFloat("ConditionSaccroupir", 1);
        }

        else if (Input.GetKeyUp(KeyCode.DownArrow))
        {
            monAnim.SetFloat("ConditionSaccroupir", 0);
        }



        // Se retourner 2/3
        if (marche > 0 && !SeRetourner) Flip();
        else if (marche < 0 && SeRetourner) Flip();
        


    }


    void FixedUpdate()
    {


    }

    void Flip()
    {
        // Se retourner 3/3
        SeRetourner = !SeRetourner;
        Vector3 changerEchelle = transform.eulerAngles;
        changerEchelle.y *= -1;
        transform.eulerAngles = changerEchelle;
    }






}








djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [DB - AL] Saut en avant (2.5D)

Message par djulio74 » 05 Juin 2020 19:09

Alors voila je t'ai fait un petit bout de script. J'ai enlevé les animation vu que moi je suis parti d'une simple capsule.
Pour ce script, il faut juste un CharacterControler sur ton perso et surtout pas de rigidbody. Le controleer n'ajoute pas de rigidbody mais un collider, donc pas besoin de collider supplémentaire. Ton perso doit avoir un meshFilter, meshRenderer, le characterControler et le script. Juste avec ça, ça marche bien.
En fait le CharacterControler simule la chute physique si le perso ne touche pas le sol, et procède a un déplacement sur le sol lorsqu'il le touche.

tu verra c'est tres simple au final ^^

Code : Tout sélectionner

    CharacterController characterController;

    public float vitesseMarche = 5.0f; // vitesse de la marche
    public float CourseMultiplicateur = 2.0f;   // multiplicateur pour passer de la vitesse de marche a celle de courir
    public float longueurSaut = 5.0f; // la longeur du saut en avant
    public float HauteurSaut = 6.0f; // hauteur général d'un saut
    private float vitesse = 0.0f; // vitesse calculée en fonction des input
    private float gravity = 9.81f;  // force de gravité pour simuler la retombée d'un saut
    private Vector3 moveDirection = Vector3.zero; // la direction général à donner au controler
    private float direction = 1.0f; // permet de savoir si on va a gauche ou a droite

    void Start()
    {
        // on essigne le controler en prenant celui présent sur le perso.
        characterController = GetComponent<CharacterController>();
    }

    void Update()
    {

        if (characterController.isGrounded)
        {   
            // defini la vitesse de deplacement en fonction de l'axe horizontal des input
            vitesse = Input.GetAxis("Horizontal") * vitesseMarche;

            // si la touche course (ici leftControl) est appuyé, mutiplie la vitesse par le CourseMultiplicateur
            if (Input.GetKey(KeyCode.LeftControl)) { vitesse *= CourseMultiplicateur; }

            // on assigne le deplacement sur l'axe x avec la vitesse 
            moveDirection.x = vitesse;

            // on defini la direction que doit avoir le pero, en fonction du signe de vitesse, en evitant de comparer avec zero
            if (vitesse > 0) direction = 1.0f;
            else if (vitesse < 0) direction = -1.0f;

            // on compare la direction du perso (la direction qui pointe devant lui, on retourne le perso s'il est différent de la direction
            if( transform.forward != Vector3.right * direction) { transform.forward = Vector3.right * direction; }
            
            // si on appui sur leftShift, on saute. Sur place si on avance pas, sinon dans la direction du deplacement
            if (Input.GetKeyDown(KeyCode.LeftShift))
            {      
                moveDirection.y = HauteurSaut;
            }

            // Variante du saut pour faire un saut en avant même si on avance pas, ici avec la touche W
            if (Input.GetKeyDown(KeyCode.W) && vitesse == 0)
            {
                moveDirection.y = HauteurSaut;
                moveDirection.x = longueurSaut * direction;
            }
        }
        
        // On ajoute a la vitesse une force de gavité pour la simuler
        moveDirection.y -= gravity * Time.deltaTime;

        // on demande au controler de bouger le perso d'apres tout ce qu'on a calculer.
        characterController.Move(moveDirection * Time.deltaTime);       
    }
    
J'ai essayé de l'annoter au mieux possible en espérant que cela marche de ton coté. J'avais paps trop menti, en enlevant les annotations, le script doit faire moins de 20 lignes. ^^

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] Saut en avant (2.5D)

Message par Derek82 » 05 Juin 2020 19:32

Ah super ! C'est très sympa de ta part, merci.

Je vais examiner et tester ça.

Une première question est-ce que la longueur d'un code joue en dehors du "confort" disons du développement ? Pour la stabilité/fluidité du projet par exemple ?

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [DB - AL] Saut en avant (2.5D)

Message par djulio74 » 05 Juin 2020 19:57

Non, je peux te monter des code de millier de lignes qui fait des milliards d'opération en moins d'une seconde. A l'inverse une seule mauvaise ligne peut faire planter unity.
La longueur du code que je te disait était juste pour appuyer le fait qu'avec les outils de unity ( ici le character controler), il n'y avait pas besoin de beaucoup écrire pour arriver au résultat que tu cherche.
Regarde l'exemple je t'ai donné et hésite pas si t'as un soucis

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] Saut en avant (2.5D)

Message par Derek82 » 05 Juin 2020 20:13

Je viens de tester, sans les animations pour l'instant, ça fonctionne au poil !
Un énorme merci d'avoir passé du temps là-dessus, surtout avec les commentaires c'est vraiment génial.

Le code est vraiment plus clair et élégant comme ça...
je n'avais pas pensé à multiplier la vitesse tout simplement.

Je ne suis pas sûr de comprendre, si on essaie de le traduire en langage parlé :

Code : Tout sélectionner

private float direction = 1.0f; // permet de savoir si on va a gauche ou a droite
> ça c'est très clair, en gros c'est comment le personnage est orienté. Donc "1.0f" c'est sa position de base (qu'elle soit à droite ou à gauche peu importe) c'est bien ça ?

Code : Tout sélectionner

// on compare la direction du perso (la direction qui pointe devant lui, on retourne le perso s'il est différent de la direction
if (transform.forward != Vector3.right * direction) { transform.forward = Vector3.right * direction; }
Et donc là je ne suis plus sûr :
"transform.forward" c'est le déplacement en avant
"!" c'est la valeur négative/opposée/contraire ?
donc tu dis "si tu le déplacement en avant se fait dans le sens contraire de l'orientation du personnage, alors..."
c'est à peu près ça ?
et la suite serait "...alors déplace-toi en avant en suivant l'orientation du personnage" et je ne comprends pas bien comment s'articule ces deux "phrases".
Désolé, je suis vraiment débutant ! :mrgreen:

et l'autre phrase que je ne suis pas sûr de décoder c'est :

Code : Tout sélectionner

moveDirection.y -= gravity * Time.deltaTime;
Bon après tu as peut-être autre chose à faire que de répondre à ces questions ! je lis la doc mais des choses m'échappe (peut-être à cause de l'anglais je ne sais pas.)

djulio74
Messages : 682
Inscription : 19 Déc 2009 22:55

Re: [DB - AL] Saut en avant (2.5D)

Message par djulio74 » 05 Juin 2020 20:50

Derek82 a écrit :
05 Juin 2020 20:13

Code : Tout sélectionner

private float direction = 1.0f; // permet de savoir si on va a gauche ou a droite
> ça c'est très clair, en gros c'est comment le personnage est orienté. Donc "1.0f" c'est sa position de base (qu'elle soit à droite ou à gauche peu importe) c'est bien ça ?
Non en fait je défini juste une valeur par défaut, de tout façon elle sera réassignée. peut très bien écrire :

Code : Tout sélectionner

private float direction; 
donc au départ sera égale a zéro, mais dans ce cas risque de problème car je multiplie un vecteur par cette valeur, et si elle n'est pas modifiée dans le script, le résultat sera un vecteur nulle.
Derek82 a écrit :
05 Juin 2020 20:13

Code : Tout sélectionner

// on compare la direction du perso (la direction qui pointe devant lui, on retourne le perso s'il est différent de la direction
if (transform.forward != Vector3.right * direction) { transform.forward = Vector3.right * direction; }
Et donc là je ne suis plus sûr :
"transform.forward" c'est le déplacement en avant
"!" c'est la valeur négative/opposée/contraire ?
donc tu dis "si tu le déplacement en avant se fait dans le sens contraire de l'orientation du personnage, alors..."
c'est à peu près ça ?
et la suite serait "...alors déplace-toi en avant en suivant l'orientation du personnage" et je ne comprends pas bien comment s'articule ces deux "phrases".
transform.forward est un vector3 qui est en gros dans la direction du regard.
tu devrait un peu plus te familiariser avec le C#. par exemple dans une condition (if) :
== compare si les deux élément son égaux
!= compare si les deux éléments sont différent
le vector transform.forward = vector3(0,0,1) dans le repère du personnage. il change si l'orientation du personnage change.
le vector3.right est le vector3(1,0,0) dans le repère monde, donc toujours égale a ça.
le sens "direction" est positif ou négatif, donc un vecteur qui regarde vers x ou -x.
ton perso doit se diriger vers x ou -x justement dans ton cas (en avant ou en arrière), il faut donc que son vecteur transform.forward = (1,0,0) ou (-1,0,0) et aura donc une rotation autour de l'axe Y (vertical) de 90 ou -90 degré.
donc si le perso ne regarde pas dans la bonne direction, on assigne son forward avec la direction voulue, ce qui reviens a lui faire faire une rotation de 180 degrés autour de Y (axe vertical)

Derek82 a écrit :
05 Juin 2020 20:13
et l'autre phrase que je ne suis pas sûr de décoder c'est :

Code : Tout sélectionner

moveDirection.y -= gravity * Time.deltaTime;
Ceci est pour simuler la gravité. la gravité ce traduit par une accélération verticale vers le base de 9.81m/s/s. donc on ajoute un déplacement vers le bas, de la valeur de la gravité, et le controler fera descendre le perso en suivant une accélération verticale s'il ne touche pas le sol.

Voila pour les explication, plus qu'as remettre les éléments manquant (animation) et nous montrer le résultat final. ;)

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Derek82
Messages : 40
Inscription : 28 Mai 2020 16:36

Re: [DB - AL] Saut en avant (2.5D)

Message par Derek82 » 05 Juin 2020 21:30

D'accord je comprends déjà bien mieux, merci pour les explications... typiquement el vector sans valeur initiale mulitplié par la suite... j'ai du faire l'erreur un nombre incalculable de fois en cherchant une solution :snif:

tu as raison, je suis vraiment trop peu à l'aise avec le C+ que je découvre.
J’espérais même éviter d'y toucher avec Unity mais bon, le plus dur est fait grâce à toi!

J'essaie d'intégrer les anims mais pour l'instant ça ne répond pas correctement... je ne sais pas où est le soucis, je vais creuser un peu. Promis, je mettrais des captures d'écran, même si pour l'instant il y a vraiment peu de choses spectaculaires à ce stade ;)

Répondre

Revenir vers « Scripting »