Bug de collision

Questions techniques liées à l’utilisation d'Unity (et n'entrant pas dans le cadre d'une des sections suivantes)
Frithy
Messages : 3
Inscription : 05 Juil 2020 21:12

Bug de collision

Message par Frithy » 05 Juil 2020 23:22

Bonjour, j'essais de faire un jeu mais j'ai quelque souci de collision.

Mon premier souci est que mon personnage traverse parfois le sol je n'arrive pas a comprendre d'où ça peut venir ni pourquoi ça se passe. (Illustration à 0:04)

Mon second c'est que parfois mon score augmente de 2 la encore je n'en comprend pas la raison. Pour faire la détection du up de score j'utilise une box collider dans le trou pour passer lorsqu'un élément de jeu entre en collision possédant le tag "Player" alors j'ajoute 1 au score et je supprime l'élément. Comment vous pouvez le voir la fonction OntriggerEnter s’exécute 2 fois de suite alors que ne devrai pas pouvoir.(Illustration à 0:03)

Merci d'avoir lu =)

Lien de la vidéo pour illustrer mes propos : https://cdn.discordapp.com/attachments/ ... -19-08.mp4

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

Re: Bug de collision

Message par djulio74 » 06 Juil 2020 07:25

Salut, pour pouvoir te répondre il faudrait que tu partage ton ou tes script ou du moins la ou les parties qui s'occupent du score.
Sans ça, pour le score qui up 2x, n'y a t il pas par hasard deux box collider au même endroit ?

Pour ce qui est de passer à travers, ça ressemble plus à un réglage de la physique ou de comment tu construit ta scène.
Fais un screen des setting de la physique, et du time aussi. En fait c'est sûrement les deux combiné, des collider d'une épaisseur trop fine et un fixe DeltaTime trop grand.
Remarque ça peut aussi venir d'une mauvaise échelle, qu'elle sont les dimensions de tes objet ? Taille du player ? Taille des obstacles ?

Dans tout les cas il faut plus d'information pour pouvoir t'aider. Ton script, des capture d'écran des réglage physique et time, du réglage de tes collider...

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Frithy
Messages : 3
Inscription : 05 Juil 2020 21:12

Re: Bug de collision

Message par Frithy » 06 Juil 2020 18:26

Salut, pour ce qui est du score il n'y a qu'un box collider.

Image

et voila le code qui me permet de modifier le score

Image

J'ai vérifié à l'aide de Debug.Log et c'est bien cette partie du code qui s'active 2 fois.
Je vous fournie aussi ce qui sert à changer le texte même si je penses que ça ne vient pas de la.

Image

Pour le joueur qui travers le sol :
Le rigidbody et le collider des platforms :

Image

le script qui fait monter les platforms :

Image

Je n'ai pas trouvé d'autre solution pour faire monter les platforms en conservant le collider original. Je m'explique, pour les platforms je pourrais utiliser un AddForce si je cochais la case "Convex" dans le collider le souci c'est que cela créer un collider sans tenir compte du trou dans la platform.

et pour finir le rigidbody du joueur :

Image

J'espère que cela vous servira et n'hésiter pas à demander d'avantage d'information si nécessaire.

Merci d'avance

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

Re: Bug de collision

Message par djulio74 » 06 Juil 2020 19:02

Alors quand tu as du code a poster utilise la balise "code" qui est le 5eme icône en partant de la gauche (ou tu as "Gras", "italique", "souligné" etc...). comme ça tu as juste a coller ton code entre les balises.
esemple : [ code] ton code ici [/code] (attention j'ai volontairement mis un espace avant le premier code)

sinon pour tes soucis :

A mon avis il faudrait déja passer les "collision detection" de tes rigidbody en "continous dynamic"
ensuite a mon sens ta box collider pour le comptage des point est trop fin, ce qui peut poser des soucis de detection.
quelle est le meshCollider de tes plateforme? son épaisseur?

Si le rigidbody de tes plateforme est en "is Kinematic", il ne devrait y avoir aucun soucis a utiliser un mesh collider non convex et donc garder tes trou dedans pour la detection.
Dans on veux déplacer un rigidbody, pour avoir une collision optimal, il faut deplacer justement le rigidbody plutot que le transform en utilisant Rigidbody.MovePosition
De plus quand un rigidbody est en is Kinematic, pas besoin de lui ajouter des "Constraints" de position ou rotation.

Partage le code complet en utilisant les balise comme je t'ai expliqué, et je verrai (ou un autre) pour te montrer des corrections éventuelles.

Dans tout les cas tes soucis vienne a mon avis d'éléments trop petits avec des vitesse trop grande (d'une frame a l'autre l'objet est passer de l'autre coté sans detecter de collision) ou d'une mauvaise gestion des déplacement de rigidbody (utilisation de transform.position plutot que de rigidbody.MovePosition)

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Frithy
Messages : 3
Inscription : 05 Juil 2020 21:12

Re: Bug de collision

Message par Frithy » 08 Juil 2020 19:26

Bonjour,
Désoler pour le temps de réponse, je n'arrives pas a comprendre ce que vous me dites de faire lorsque vous parlez du "is Kinematic".

Pour ce qui est du Rigidbody que je dois déplacer au lieu du transform, la variable que vous me proposez je n'arrives pas à l'obtenir.

J'ai aussi augmenté la taille de mon cube faisant la détection pour le score (BoxCollider d'une taille y de 0.7 sachant que le BoxCollider de mon joueur fait 1.45). Mais cela n'a rien changé, j'ai toujours le souci du score x2.

Mes codes :

Mon object contenant les platforms :

Code : Tout sélectionner

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

public class Rotation : MonoBehaviour
{
    public float speedClimb;
    public float speedRotation;
    public bool wallRight;
    public bool wallLeft;

    public Collider right;
    public Collider left;

    public Rigidbody player;
    public Camera view;

    public List<Collider> colliders;
    public GameObject tester;

    float rotationY;

    private void Start()
    {
        colliders = new List<Collider>();
    }

    // Update is called once per frame
    void Update()
    {
        rotationY = Input.GetAxisRaw("Horizontal") * speedRotation;

        colliders = tester.GetComponent<PlayableElement>().GetList();
        wallRight = right.GetComponent<DetectElement>().GetCollision();
        wallLeft = left.GetComponent<DetectElement>().GetCollision();
    }

    private void FixedUpdate()
    {
        //Montée des platforms
        transform.Translate(0, speedClimb, 0);

        //Si le joueur dessend trop bas les platforms montent plus vite
        if(player.position.y < view.transform.position.y-6)
        {
            transform.Translate(0, 0.1f, 0);
        }

        //Rotation des platforms
        if ((rotationY > 0) && !wallRight)
        {
            transform.Rotate(0, rotationY, 0);
        }else if ((rotationY < 0) && !wallLeft)
        {
            transform.Rotate(0, rotationY, 0);
        }
    }

}
L'object qui génère les platforms (la création fonctionne bien mais j'arrive pas à bien faire remonter le point de spawn):

Code : Tout sélectionner

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

public class MapGenerator : MonoBehaviour
{
    private const float PLAYER_DISTANCE_SPAWN_LEVEL_PART = 30f;

    public Transform platform_start;
    public List<Transform> platforms; 
    public Transform tron;
    public Transform player;
    public float SpeedClimb;
    public Camera view;

    Vector3 lastEndPostion;
    private void Awake()
    {
        lastEndPostion = platform_start.Find("EndPosition").position;
    }

    private void Update()
    {
        lastEndPostion += new Vector3(0,0.001f,0);

        if (player.position.y < view.transform.position.y - 6)
        {
            lastEndPostion += new Vector3(0, 0.026f, 0);
        }

        if (Vector3.Distance(player.position, lastEndPostion) < PLAYER_DISTANCE_SPAWN_LEVEL_PART)
        {
            SpawnLevelPart();
        }
    }

    private void SpawnLevelPart()
    {
        Transform choseLevelPart = platforms[Random.Range(0,platforms.Count)];
        Transform lastLevelPartTransform = SpawnLevel(choseLevelPart,lastEndPostion);
        lastEndPostion = lastLevelPartTransform.Find("EndPosition").position;
    }

    private Transform SpawnLevel(Transform levelPart, Vector3 spawnPosition)
    {
        Transform lastPartTransform = Instantiate(levelPart, spawnPosition, Quaternion.Euler(0,Random.Range(0,360),0), tron);
        return lastPartTransform;
    }
}
Le controller de mon joueur :

Code : Tout sélectionner

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

public class ControllerPlayer : MonoBehaviour
{
    public Rigidbody rb;
    public float forceJump;
    public bool isGrounded;
    public float distToGround;

    public Collider rbFeet;

    bool temp = true;

    private void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("Jump") && isGrounded)
        {
            rb.AddForce(Vector3.up * forceJump);
        }

    }

    void OnTriggerStay(Collider other)
    {

        if (other.CompareTag("Ground"))
        {
            isGrounded = true;
        }
    }

    void OnTriggerExit(Collider other)
    {
        isGrounded = false;
    }

}
Ce qui me permet de détecter si la rotation peut se faire à gauche et à droite :

Code : Tout sélectionner

using UnityEngine;

public class DetectElement : MonoBehaviour
{
    public bool collision;

    public bool GetCollision()
    {
        return collision;
    }
    private void OnTriggerEnter(Collider other)
    {
        if(!other.CompareTag("Detector") && !other.CompareTag("Pickable"))
        {
            collision = true;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        collision = false;
    }
}
Mon code gérant l'inventaire :

Code : Tout sélectionner

using UnityEngine;
using UnityEngine.UI;

public class Inventory : MonoBehaviour
{
    public int coinsCount;
    public int score;

    public Text scoreText;

    public static Inventory instance;

    private void Awake()
    {
        if(instance != null)
        {
            Debug.LogWarning("Plus d'un inventaire créé");
            return;
        }

        instance = this;
    }

    public void AddCoins(int count)
    {
        coinsCount += count;
    }

    public void AddPoint(int count)
    {
        score += count;
        scoreText.text = score.ToString();
    }
}
Et les 2 codes lui faisant appel :

Le score :

Code : Tout sélectionner

using UnityEngine;

public class Score : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            Destroy(gameObject);
            Inventory.instance.AddPoint(1);
        }
    }
}
Les pièces :

Code : Tout sélectionner

using UnityEngine;

public class PickupObject : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            Inventory.instance.AddCoins(1);
            Destroy(gameObject);
        }
    }
}
J'aimerai savoir si il est possible de modifier la gravité pour quelle devient moins réel, que lorsque l'on tombe on trombe toujours de la même distance, qu'il n'y est pas d'accélération en gros.

Merci d'avance pour l'aide que vous me donnez.

Répondre

Revenir vers « Unity le logiciel »