Wall Jump donne l'impression de se téléporter.

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Gatefiz
Messages : 13
Inscription : 28 Oct 2014 01:45

Wall Jump donne l'impression de se téléporter.

Message par Gatefiz » 12 Juil 2021 14:58

Bonjour à tous,

J'effectue quelques tests, et j'essaye actuellement de faire un wall jump à mon personnage.
Malheureusement il donne plutôt l'impression de se téléporter que de sauter du mur.
Voici le code;

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveTest : MonoBehaviour
{
    //Liste des variables
    #region Variables
    public Rigidbody2D rb;

    //Definit la vitesse de deplacement du personnage
    public float moveSpeed;

    private Vector3 velocity = Vector3.zero;

    public Animator animator;

    public SpriteRenderer spriteRenderer;

    //Definit si le personnage est au sol
    public bool isJumping;

    //Gestion de collision du sol
    public bool isGrounded;
    public Transform groundCheckLeft;
    public Transform groundCheckRight;

    //Gestion de collision mur gauche
    public bool isOnLeftWall;
    public Transform wallLeftCheckUp;
    public Transform wallLeftCheckDown;

    //Gestion de collision mur droit
    public bool isOnRightWall;
    public Transform wallRightCheckUp;
    public Transform wallRightCheckDown;

    //Appel des methodes
    private bool executeJump;
    private bool executeWallJump;
    private float movementPlayer;

    //Definit quel mur est touché
    private string wallSideArgument;
    #endregion

    //Lu uniquement au demarrage du script
    #region Start
    void Start()
    {
        executeJump = false;
    }
    #endregion

    //Lu a interval regulier
    #region FixedUpdate
    void FixedUpdate()
    {
        Move(movementPlayer);

        isGrounded = Physics2D.OverlapArea(groundCheckLeft.position, groundCheckRight.position); //Verifie la collision avec le sol
        isOnLeftWall = Physics2D.OverlapArea(wallLeftCheckUp.position, wallLeftCheckDown.position); //Verifie la collision avec un mur à gauche
        isOnRightWall = Physics2D.OverlapArea(wallRightCheckUp.position, wallRightCheckDown.position);//Verifie la collifion avec un mur à droite

        //Appel les methodes
        if (executeJump) {
            Jump();
        }

        if (executeWallJump)
        {
            WallJump(wallSideArgument);
        }
        
    }
    #endregion

    //Lecture à chaque frame
    #region update
    void Update()
    {


        if (Input.GetKeyDown("space") && isGrounded)
        {
            executeJump = true;
        }

        if (Input.GetKeyDown("space") && isGrounded == false && isOnLeftWall)
        {
            wallSideArgument = "left";
            executeWallJump = true;
        }

        if (Input.GetKeyDown("space") && isGrounded == false && isOnRightWall)
        {
            wallSideArgument = "right";
            executeWallJump = true;
        }

        movementPlayer = Input.GetAxis("Horizontal") * moveSpeed * Time.fixedDeltaTime;

        animator.SetBool("isGrounded", isGrounded);
    }
    #endregion

    //Cette methode permet de deplacer le personnage
    #region Move
    private void Move(float _movementplayer) {
        rb.velocity = new Vector2(_movementplayer, rb.velocity.y);
        float charactervelocity = Mathf.Abs(rb.velocity.x);
        Flip(rb.velocity.x);
        animator.SetFloat("Speed", charactervelocity);
    }
    #endregion

    //Cette methode permet d'effectuer un simple saut
    #region Jump  

    private void Jump() {
        Vector3 jump = new Vector3(0, 10, 0);
        rb.AddForce(jump, ForceMode2D.Impulse);
        executeJump = false;
    }
    #endregion

    //Cette methode permet d'effectuer des wall jump
    #region WallJump
    private void WallJump(string _wallSide)
    {
        switch (_wallSide)
        {
            case "left":
                //Initialise la velocité a 0 pour ne pas perturber le saut
                rb.velocity = new Vector2(0, 0);

                //Defini la direction du wallJump
                Vector3 leftWallJump = new Vector3( 30 , 7 , 0);

                //Applique le saut sur le personnage
                rb.AddForce(leftWallJump, ForceMode2D.Impulse);

                //Termine la sequence de saut
                executeWallJump = false;

                break;

            
        }

       
        
    }
    #endregion

    // Cette methode permet de tourner le personnage selon sa direction
    #region Flip
    void Flip(float _velocity) 
    {
        if (_velocity > 0.1f)
        {
            spriteRenderer.flipX = false;
        }
        else if (_velocity < -0.1f)
        {
            spriteRenderer.flipX = true;
        }
    }
    #endregion
}
Merci à ceux qui m'aideront =)

Avatar de l’utilisateur
Max
Messages : 8764
Inscription : 30 Juil 2011 13:57
Contact :

Re: Wall Jump donne l'impression de se téléporter.

Message par Max » 12 Juil 2021 17:20

Bonjour,
Gatefiz a écrit :
12 Juil 2021 14:58
Malheureusement il donne plutôt l'impression de se téléporter que de sauter du mur.
par téléporté, tu veux dire passer d'une position à une autre sans transition ? De ce que j'ai pu lire au niveau de ton code, niveau principe cela semble correct. Après est-ce peut-être du à un dosage des valeur de l'AddForce ?
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Gatefiz
Messages : 13
Inscription : 28 Oct 2014 01:45

Re: Wall Jump donne l'impression de se téléporter.

Message par Gatefiz » 12 Juil 2021 17:28

C'est exactement ce que je veux dire, il passe d'une position à l'autre sans que l'on voit le trajet.

J'ai essayé de réduire la force, mais ça ne fait que réduire la distance entre le point d'arrivée et le mur. De plus, la force appliquée est déjà insuffisante.

Je me creuse la tête, mais je ne trouve pas du tout quel est le problème.

J'ai trouvé pas mal de sujets là dessus sur google, mais rien n'a solutionné mon problème.

Si une âme charitable passe par là =)

Avatar de l’utilisateur
Max
Messages : 8764
Inscription : 30 Juil 2011 13:57
Contact :

Re: Wall Jump donne l'impression de se téléporter.

Message par Max » 12 Juil 2021 17:59

Si tu isole chaque fonction (juste le Jump par exemple), comment cela se passe ?
Je vois dans ton code deux action possible lors d'un appui sur la barre espace: Jump() et WallJump().
N'y aurait-il pas interférence entre les deux ?
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Gatefiz
Messages : 13
Inscription : 28 Oct 2014 01:45

Re: Wall Jump donne l'impression de se téléporter.

Message par Gatefiz » 12 Juil 2021 18:16

Mais la bool isGrounded n'est pas une condition qui évite justement que les deux méthodes soient appelées ?

Avatar de l’utilisateur
Max
Messages : 8764
Inscription : 30 Juil 2011 13:57
Contact :

Re: Wall Jump donne l'impression de se téléporter.

Message par Max » 12 Juil 2021 20:05

Gatefiz a écrit :
12 Juil 2021 18:16
Mais la bool isGrounded n'est pas une condition qui évite justement que les deux méthodes soient appelées ?
en théorie oui, mais sont elles valides par rapport à ce qui est attendu. Tu peux essayer de les vérifier (isGrounded et isOnLeftWall/isOnRightWall). Perso je chercherais déjà de ce coté.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Gatefiz
Messages : 13
Inscription : 28 Oct 2014 01:45

Re: Wall Jump donne l'impression de se téléporter.

Message par Gatefiz » 13 Juil 2021 09:57

Si j'isole Jump(), ça fonctionne parfaitement.

Et si j'isole WallJump(), en plaçant mon personnage contre un mur hors sol ( en remplissant les conditions ), le problème persiste.

J'ai tenté de tout repasser en Vector2, je me suis dit que le problème venait de là.
J'ai modifié le type de force ( Impulse, Force, noone ).
J'ai retiré la méthode Flip, au cas ou elle déplace mes entités.
J'ai retiré le switch, en remplaçant le string par un int ( 1 / -1 ) qui définit le côté ( droite ou gauche ).

Et là j'en étais à me dire que j'allais égorger un lama sur l'autel des dieux afin d'avoir un indice quant à quoi faire.

Avatar de l’utilisateur
Max
Messages : 8764
Inscription : 30 Juil 2011 13:57
Contact :

Re: Wall Jump donne l'impression de se téléporter.

Message par Max » 13 Juil 2021 10:37

Un truc me chagrine dans ton code. C'est dans l'utilisation des Physics2D.OverlapArea(). Tu récupères en résultat un boolean, alors que si je regarde la doc, est attendu plutôt un Collider2D il me semble.
Il est étrange que tu n'est pas de warning à ce sujet (chez moi non plus d'ailleurs).
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Gatefiz
Messages : 13
Inscription : 28 Oct 2014 01:45

Re: Wall Jump donne l'impression de se téléporter.

Message par Gatefiz » 13 Juil 2021 10:51

J'ai fait ça en suivant les tutos de Unity tuto fr:
Tuto fr

Je vais essayer de creuser un peu dans la direction que tu me donnes.

Sur un serveur discord, un utilisateur me dit que le problème vient du fait que je rentre le vecteur à la main, mais je n'ai pas trouvé de solution. Voilà le code avec les différentes modifications.
(en gros, j'ai passé le calcul du vecteur dans le fixedupdate )

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MoveTest : MonoBehaviour
{
    //Liste des variables
    #region Variables
    public Rigidbody2D rb;

    //Definit la vitesse de deplacement du personnage
    public float moveSpeed;

    private Vector3 velocity = Vector3.zero;

    public Animator animator;

    public SpriteRenderer spriteRenderer;

    //Definit si le personnage est au sol
    public bool isJumping;

    //Gestion de collision du sol
    public bool isGrounded;
    public Transform groundCheckLeft;
    public Transform groundCheckRight;

    //Gestion de collision mur gauche
    public bool isOnLeftWall;
    public Transform wallLeftCheckUp;
    public Transform wallLeftCheckDown;

    //Gestion de collision mur droit
    public bool isOnRightWall;
    public Transform wallRightCheckUp;
    public Transform wallRightCheckDown;

    //Appel des methodes
    private bool executeJump;
    private bool executeWallJump;
    private float movementPlayer;

    //Definit quel mur est touché
    private int wallSideArgument;
    #endregion

    //Lu uniquement au demarrage du script
    #region Start
    void Start()
    {
        executeJump = false;
    }
    #endregion

    //Lu a interval regulier
    #region FixedUpdate
    void FixedUpdate()
    {
        Move(movementPlayer);

        isGrounded = Physics2D.OverlapArea(groundCheckLeft.position, groundCheckRight.position); //Verifie la collision avec le sol
        isOnLeftWall = Physics2D.OverlapArea(wallLeftCheckUp.position, wallLeftCheckDown.position); //Verifie la collision avec un mur à gauche
        isOnRightWall = Physics2D.OverlapArea(wallRightCheckUp.position, wallRightCheckDown.position);//Verifie la collifion avec un mur à droite

        //Appel les methodes
        if (executeJump)
        {
            Jump();
        }

        if (executeWallJump)
        {
            //Defini la direction du wallJump
            Vector3 leftWallJump = new Vector2(wallSideArgument * 9, 8);
            WallJump(wallSideArgument, leftWallJump);
        }

    }
    #endregion

    //Lecture à chaque frame
    #region update
    void Update()
    {


        if (Input.GetKeyDown("space") && isGrounded)
        {
            executeJump = true;
        }

        if (Input.GetKeyDown("space") && isGrounded == false && isOnLeftWall)
        {
            wallSideArgument = 1;
            executeWallJump = true;
        }

        if (Input.GetKeyDown("space") && isGrounded == false && isOnRightWall)
        {
            wallSideArgument = -1;
            executeWallJump = true;
        }

        movementPlayer = Input.GetAxis("Horizontal") * moveSpeed;

        animator.SetBool("isGrounded", isGrounded);
    }
    #endregion

    //Cette methode permet de deplacer le personnage
    #region Move
    private void Move(float _movementplayer)
    {
        rb.velocity = new Vector2(_movementplayer, rb.velocity.y);
        float charactervelocity = Mathf.Abs(rb.velocity.x);
        Flip(rb.velocity.x);
        animator.SetFloat("Speed", charactervelocity);
    }
    #endregion

    //Cette methode permet d'effectuer un simple saut
    #region Jump  

    private void Jump()
    {
        Vector3 jump = new Vector3(0, 10, 0);
        rb.AddForce(jump, ForceMode2D.Impulse);
        executeJump = false;
    }
    #endregion

    //Cette methode permet d'effectuer des wall jump
    #region WallJump
    private void WallJump(int _wallSide, Vector2 _wallJump)
    {
        //Initialise la velocité a 0 pour ne pas perturber le saut
        rb.velocity = new Vector2(0, 0);

        

        //Applique le saut sur le personnage
        rb.AddForce(_wallJump, ForceMode2D.Impulse);


        //Termine la sequence de saut
        executeWallJump = false;


    }
    #endregion

    // Cette methode permet de tourner le personnage selon sa direction
    #region Flip
    void Flip(float _velocity)
    {
        if (_velocity > 0.1f)
        {
            spriteRenderer.flipX = false;
        }
        else if (_velocity < -0.1f)
        {
            spriteRenderer.flipX = true;
        }
    }
    #endregion
}


EDIT: Un utilisateur de ce forum est déjà intervenu sur le problème du bool:
Forum Unity3d-france

Et il explique que c'est viable, car "Apparement, le fait qu'il y ait un collider ou non de retourné est automatiquement converti en true ou false pour renseigner la valeur de la variable isGrounded."

Avatar de l’utilisateur
Max
Messages : 8764
Inscription : 30 Juil 2011 13:57
Contact :

Re: Wall Jump donne l'impression de se téléporter.

Message par Max » 13 Juil 2021 11:24

Oui, n'ayant pas de warning de toute façon, on peut penser que c'est logique ce genre de transtypage en retour (si non null retourne true, sinon retourne false).
Concernant les valeurs en dur dans le code, de base on évite. Après la partie souligné sur le Discord par l'intervenant est certainement celle-ci:

Code : Tout sélectionner

        if (executeWallJump)
        {
            //Defini la direction du wallJump
            Vector3 leftWallJump = new Vector2(wallSideArgument * 9, 8);
            WallJump(wallSideArgument, leftWallJump);
        }

Maintenant il faut voir comment la valeur de rebond doit être déterminée ? Elle ne peut pas être liée à la surface rencontrée vu que tu n'as pas d'info dessus issues du Physics2D.OverlapArea. Donc tu passes par des valeurs fixes. A toi de tester plusieurs valeurs, en rendant accessible la valeur du vecteur rebond au niveau de l'inspector.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Répondre

Revenir vers « Scripting »