Problème de collisions

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Mysteries
Messages : 4
Inscription : 26 Déc 2021 16:10

Problème de collisions

Message par Mysteries » 26 Déc 2021 23:01

Bonjour à tous,

Je viens de me lancer sur Unity et j'ai un projet. C'est un jeu en 2D où on déplace un personnage, mais une fois parti dans une direction, il ne peut pas s'arrêter avant de rencontrer un mur.

Pour l'instant je m'occupe seulement du gameplay basique. J'ai créé un script qui fonctionne comme je le voulais à un détail près : lors des déplacements, mon personnage s'arrête un peu après la collision : au lieu d'arriver en Y=9 par exemple il arrive en 9.0004.

Dans ma scène, j'ai seulement mon personnage, auquel sont attachés le script, un RigidBody et un BoxCollider2D, et des obstacles représentés par des cubes/rectangles avec juste un BoxCollider2D. J'ai tenté des tas de choses mais le problème n'est jamais résolu. A cause de ça, mon personnage va parfois s'arrêter en longeant un mur, comme s'il y avait de la friction, parce qu'il est légèrement décalé.

Exemple :
Unity1.PNG
Unity1.PNG (5.88 Kio) Consulté 1415 fois
Ici c'est la position de départ. Je vais à gauche :
Unity2.PNG
Unity2.PNG (6.1 Kio) Consulté 1415 fois
Et là, en retournant à droite :
Unity3.PNG
Unity3.PNG (5.97 Kio) Consulté 1415 fois
Comme je suis un peu trop bas, je "frotte" le bord et donc je m'arrête au lieu d'aller jusqu'au bout.

Est-ce que quelqu'un a une solution ?

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

Re: Problème de collisions

Message par Max » 27 Déc 2021 12:04

Bonjour Mysteries,

ce qui serait intéressant, c'est d'avoir le script.
Peux tu le poster, cela nous aiderait ;)
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

Mysteries
Messages : 4
Inscription : 26 Déc 2021 16:10

Re: Problème de collisions

Message par Mysteries » 27 Déc 2021 13:31

Bonjour Max,

n'étant pas chez moi je ne peux pas fournir le script avant demain.
J'applique à mon rigidBody un Vector2 constant comme velocity pour le déplacement, et j'ai un onCollisionEnter2D dans lequel je passe cette velocity à Vector2(0,0).

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

Re: Problème de collisions

Message par Max » 27 Déc 2021 15:43

il serait du coup aussi inintéressant par la même occasion de voir comment sont configurés le BoxCollider2D et le Rigidbody2D.
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

Mysteries
Messages : 4
Inscription : 26 Déc 2021 16:10

Re: Problème de collisions

Message par Mysteries » 29 Déc 2021 15:34

Voici la configuration du personnage :
player_1.PNG
player_1.PNG (62.52 Kio) Consulté 1285 fois
player_2.PNG
player_2.PNG (54.16 Kio) Consulté 1285 fois
Voici la configuration des obstacles :
obstacle.PNG
obstacle.PNG (44.11 Kio) Consulté 1285 fois
Et je n'arrive pas à mettre le script en pièce-jointe donc le voici :

Code : Tout sélectionner

public class PlayerMovement : MonoBehaviour
{

    public float moveSpeed;
    public Rigidbody2D rb;
    private Vector2 moveDirection;
    public bool moving = false;
    private List<string> collisionSides = new List<string>();

    // Update is called once per frame
    void Update()
    {
        ProcessInputs();
    }

    private void FixedUpdate()
    {
        Move();
    }

    //Processing the inputs
    void ProcessInputs()
    {
        if (!moving)
        {
            //Get the axis of the movement (horizontal or vertical)
            float moveX = Input.GetAxisRaw("Horizontal");
            float moveY = Input.GetAxisRaw("Vertical");

            //Get the move Vector (if no collision)
            if (moveX != 0)
            {
                //Checking the collisions
                if ((moveX > 0 && !collisionSides.Contains("right")) || (moveX < 0 && !collisionSides.Contains("left")))
                {
                    moveX = moveX / Mathf.Abs(moveX);
                    moveY = 0;

                    moveDirection = new Vector2(moveX, moveY);
                    moving = true;

                    collisionSides.Clear();
                }

            } else if (moveY != 0)
            {
                print(rb.position);
                print(character.transform.position);

                if ((moveY > 0 && !collisionSides.Contains("up")) || (moveY < 0 && !collisionSides.Contains("down")))
                {
                    moveY = moveY / Mathf.Abs(moveY);
                    moveX = 0;

                    moveDirection = new Vector2(moveX, moveY);
                    moving = true;

                    collisionSides.Clear();
                }
            }
        }
    }

    void Move()
    {
        rb.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        moveDirection = new Vector2(0, 0);
        rb.velocity = moveDirection;
        moving = false;

        List<Collider2D> colliders = new List<Collider2D>();
        Physics2D.OverlapCircle(rb.position, 0.75f, new ContactFilter2D(), colliders);

        float positionX = Convert.ToSingle(Math.Round(rb.position.x * 2, MidpointRounding.AwayFromZero) / 2);
        float positionY = Convert.ToSingle(Math.Round(rb.position.y * 2, MidpointRounding.AwayFromZero) / 2);

        foreach (Collider2D collider in colliders)
        {
            //Up
            if (collider.OverlapPoint(new Vector2(positionX, positionY + 0.6f)))
            {
                collisionSides.Add("up");
            }
            //Down
            else if (collider.OverlapPoint(new Vector2(positionX, positionY - 0.6f)))
            {
                collisionSides.Add("down");
            }
            //Left
            else if (collider.OverlapPoint(new Vector2(positionX - 0.6f, positionY)))
            {
                collisionSides.Add("left");
            }
            //Right
            else if (collider.OverlapPoint(new Vector2(positionX + 0.6f, positionY)))
            {
                collisionSides.Add("right");
            }
        }

    }
}

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

Re: Problème de collisions

Message par Max » 30 Déc 2021 12:25

Bonjour,

C'est basé sur un tuto ? J'avoue avoir du mal à visualiser l'effet de l'ensemble du script (bon j'avoue que je n'ai pas l’esprit très vif en ce moment :mrgreen: )
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

Mysteries
Messages : 4
Inscription : 26 Déc 2021 16:10

Re: Problème de collisions

Message par Mysteries » 30 Déc 2021 13:21

Le tout début vient d'un tuto mais le reste c'est moi qui l'ai fait.
Le fonctionnement est assez simple : lorsque le personnage est en mouvement, la variable "moving" est mise à true pour empêcher le joueur de changer de direction pendant le déplacement, et un vecteur et appliqué pour déplacer le personnage. Les collisions sont détectées par les ColliderBox et en cas de collision je crée temporairement un cercle de collision autour du personnage. Ca me permet de savoir à quels endroits autour du personnage il y a des murs (en haut, en bas, à gauche, à droite). Grâce à ça je sais dans quelles directions le personnage ne pourra pas aller au prochain déplacement puisqu'il y a un mur à cet endroit là.

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

Re: Problème de collisions

Message par Max » 31 Déc 2021 12:20

Hmm, oui je vois bien le truc.
Le fait de passer par les RigidBody fait que cela sera toujours difficile d'avoir des valeur strictes en terme de déplacement, et tu te trouveras souvent face à un cas particulier ou tes collider auront tendance à légèrement se chevaucher, phénomène qui ne fera que d’amplifier avec le temps de jeu je pense.
Personnellement, sur ce genre de gameplay je sera plutôt passé par une détection par Raycast. Cela t’affranchis des RigidBody;
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 »