Les collisions et un effet bounce

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
DJ-OMZ
Messages : 129
Inscription : 11 Jan 2017 13:15

Les collisions et un effet bounce

Message par DJ-OMZ » 27 Avr 2017 11:23

Hello,

J'aimerais faire un petit jeu de voitures.

Pour le moment, j'ai mon cube, qui peut accelerer en jouant sur son axe z, tourner sur son axe y.

J'ai envie de mettre un système de collisions contre des murs, avec un effet de rebondissement et perte de vitesse. Je vous avoue que j'ai du mal...

Peut-être existe-t-il des exemples sur lesquels je pourrais m'inspirer ? Je cherche un truc style Mario kart, pas de degats ou de voiture qui vole dans le ciel mais juste bloqué au sol avec un effet de rebondissement...

Pour le moment, dans mon OnCollisionEnter, j'ai ceci :

Code : Tout sélectionner

if (col.transform.parent.name == "Obstacles")
        {
            Vector3 dir = col.contacts[0].point - transform.position;
            dir = -dir.normalized;
            zSpeed = dir.z*-20;
            xSpeed = dir.x*10;
            Debug.Log("Collision point z : " + col.contacts[0].point.z);
            Debug.Log("Collision point x : " + col.contacts[0].point.x);
            Debug.Log("Position point x : " + transform.position.x);
            if (col.contacts[0].point.x < transform.position.x)
            {
                xSpeed *= -1;
            }
            if (zSpeed > -3)
            {
                xSpeed *= 3;
            }
        }
Le probleme c'est que ça marche quand je touche un mur a droite, mais pas a gauche... Il faut que je multiplie mon x par -1. Vous pouvez voir ma tentative dans le if qui compare le point x de collision et le transform.position.x, mais c'est un echec...

En résumé je suis pas loin de ce que je veux, il me faut juste un moyen de savoir par ou j'ai touché et de rebondir de l'autre coté, quelqu'un sait comment faire ?

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: Les collisions et un effet bounce

Message par evereal » 27 Avr 2017 14:24

Hello,

Pourquoi ne pas utiliser simplement le component Physic Material ?
https://docs.unity3d.com/Manual/class-P ... erial.html
la propriété Bounciness semble correspondre a toute tes attentes.
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

Avatar de l’utilisateur
DJ-OMZ
Messages : 129
Inscription : 11 Jan 2017 13:15

Re: Les collisions et un effet bounce

Message par DJ-OMZ » 28 Avr 2017 09:52

Hello,

J'y comprends rien, j'ai enlevé mon code et testé cet outil mais j'obtiens des bugs.

L'outil doit être appliqué a mon véhicule ou a mon mur ?

Est-ce qu'il y a des pré requis comme par exemple le mur doit avoir un rigidBody ect ?

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: Les collisions et un effet bounce

Message par evereal » 28 Avr 2017 11:14

Sur le véhicule et le mur.il n'y a pas de prérequis, il faut juste appliquer ton matériel physique sur un collider.
Après dans la logique des choses, tu auras un rigibody sur ton véhicule mais pas de rigidbody sur ton mur.

https://unity3d.com/fr/learn/tutorials/ ... -materials
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

Avatar de l’utilisateur
DJ-OMZ
Messages : 129
Inscription : 11 Jan 2017 13:15

Re: Les collisions et un effet bounce

Message par DJ-OMZ » 28 Avr 2017 12:55

J'ai beau essayer je n'ai pas le résultat attendu.
Lorsque j'entre en collision, aucun rebond même avec le Bounciness au max, et quand je fonce droit dans le mur je passe a travers...

D'ailleurs avec mon code c'est pareil, quand ma vitesse devient assez importante je passe a travers le mur, vous savez pourquoi ?

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: Les collisions et un effet bounce

Message par evereal » 28 Avr 2017 15:14

D'ailleurs avec mon code c'est pareil, quand ma vitesse devient assez importante je passe a travers le mur, vous savez pourquoi ?
En informatique, il n'existe pas de déplacement continu comme dans la vraie vie, on se contente de recalculer à chaque itération la nouvelle position et on "téléporte" notre objet a cette position.
Avec une vitesse suffisamment grande, la nouvelle position calculée de ta voiture se trouve de l'autre coté de ton mur ce qui donne l'illusion d'être passé au travers.

C'est une erreur commune quand on utilise des projectiles ayant une grande vélocité mais ça m'étonne beaucoup d'avoir cela pour une voiture. Ton mur n'est qu'un simple panneau sans profondeur ? Tu ne mélange pas d’élément 2D avec éléments 3D ?
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

Avatar de l’utilisateur
DJ-OMZ
Messages : 129
Inscription : 11 Jan 2017 13:15

Re: Les collisions et un effet bounce

Message par DJ-OMZ » 28 Avr 2017 15:50

Pas de 2D, et un mur assez épais. J'ai une vitesse assez élevée :lol:

Dans mon cas actuel, le code que j'utilise est dans une méthode OnCollisionEnter. J'ai essayé de rendre mon mur plus large mais ça n'as pas changé grand chose.

Est-ce que je devrais faire ça dans un OnCollisionStay tu penses ?

Avatar de l’utilisateur
DevAmat
Messages : 435
Inscription : 23 Nov 2016 11:50

Re: Les collisions et un effet bounce

Message par DevAmat » 28 Avr 2017 16:15

Peux tu mettre ici le morceau de code qui déplace ton objet pour que l'on voit ta méthode? Car selon la méthode, ce genre d'effet non voulu est plus ou moins susceptible d'arriver.

Avatar de l’utilisateur
DJ-OMZ
Messages : 129
Inscription : 11 Jan 2017 13:15

Re: Les collisions et un effet bounce

Message par DJ-OMZ » 28 Avr 2017 16:47

Oulala je sens que je vais me faire insulter lol, ne jugez pas je debute haha.

Donc voila le code de mon cube qui se déplace :

Code : Tout sélectionner

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

public class PlayerMovement : MonoBehaviour {
    //Propriétés de mouvement
    public float inputDelay = 0.1f; //Delay Input
    public float rotateVel = 100;
    public float vitesseMax = 100;
    public float acceleration = 6;
    public float zSpeed = 0f;
    public float xSpeed = 0f;
    public float angleVirage = 1;
    Vector3 dir = Vector3.zero;
    Quaternion targetRotation;
    Rigidbody rBody;
    float forwardInput, turnInput;
    Vector3 velocity = Vector3.zero;
    bool avancer;
    float distToGround;


    // Use this for initialization
    void Start () {
        targetRotation = transform.rotation;
        avancer = true;
        if (GetComponent<Rigidbody>())
        {
            rBody = GetComponent<Rigidbody>();
        }
        else
        {
            Debug.LogError("The character needs a rigidbody.");
        }
        forwardInput = turnInput = 0;
        distToGround = GetComponent<Collider>().bounds.extents.y;
    }
   
    // Update is called once per frame
    void Update () {
        GetInput();
        Turn();
        Run();
        if (isGrounded())
        {
            //Debug.Log("Au Sol");
        }
        else
        {
            //Debug.Log("Dans les airs !!!");
        }
    }

    void OnCollisionEnter(Collision col)
    {
        if (col.transform.gameObject.name == "Floor1")
        {
            //Debug.Log("Collision avec Floor1");
        }
        if (col.transform.parent.name == "Obstacles")
        {
            Vector3 dir = col.contacts[0].point - transform.position;
            dir = -dir.normalized;
            zSpeed = dir.z * -20 * (zSpeed / 10);
            xSpeed = dir.x * 10;

            //Si le mur est a gauche
            if (col.transform.position.x < transform.position.x)
            {
                ////xSpeed *= -1;
                //zSpeed *= -1;

                //if (transform.eulerAngles.y < -90 || transform.eulerAngles.y > 90)
                //{
                //    xSpeed *= -1;
                //    //zSpeed *= -1;
                //}
            }
            else //Si le mur est a droite
            {
                if (transform.eulerAngles.y < -90 || transform.eulerAngles.y > 90)
                {
                    xSpeed *= -1;
                    zSpeed *= -1;
                    //Si la collision est faible on decale du mur pour pas rester collé
                    if (zSpeed > 3)
                    {
                        xSpeed *= 3;
                        Debug.Log("Decale : " + zSpeed);
                    }
                    Debug.Log("Valeur de z : " + zSpeed);
                }
                else
                {
                    //Si la collision est faible on decale du mur pour pas rester collé
                    if (zSpeed > -3)
                    {
                        xSpeed *= 3;
                        Debug.Log("Decale : " + zSpeed);
                    }
                    Debug.Log("Valeur de z : " + zSpeed);
                }
            }
        }
        if (col.transform.parent.name == "Boosters")
        {
            zSpeed = vitesseMax;
            transform.rotation = col.transform.rotation;
            targetRotation = transform.rotation;
        }
    }

    void OnCollisionStay(Collision col)
    {
        if (col.transform.parent.name == "Obstacles")
        {
            avancer = false;
        }
    }

    void OnCollisionExit(Collision col)
    {
        if (col.transform.parent.name == "Obstacles")
        {
            avancer = true;
        }
    }

    void FixedUpdate()
    {
        regleXSpeed();
        Run();
        transform.Translate(velocity);
    }

    bool isGrounded()
    {
        return Physics.Raycast(transform.position, -Vector3.up, distToGround+0.1f);
    }

    public Quaternion TargetRotation
    {
        get { return targetRotation; }
    }

    void GetInput()
    {
        forwardInput = Input.GetAxis("Run");
        turnInput = Input.GetAxis("Horizontal");
    }

    void Turn()
    {
        if (Mathf.Abs(turnInput) > inputDelay)
        {
                angleVirage = 1 - (zSpeed / 100);
            if (angleVirage < 0.5f) { angleVirage = 0.5f; }
                targetRotation *= Quaternion.AngleAxis(rotateVel * turnInput * Time.deltaTime * angleVirage, Vector3.up);
                transform.rotation = targetRotation;
        }
    }

    void Run()
    {
        if (avancer) //Si on est pas en collision avec un mur
        {
            if (Mathf.Abs(forwardInput) > inputDelay)
            {
                velocity.z = zSpeed * Time.deltaTime;
                velocity.x = xSpeed * Time.deltaTime;
                if (vitesseMax > zSpeed)
                {
                    zSpeed += acceleration * Time.deltaTime;
                }
            }
            else
            {
                velocity.z = zSpeed * Time.deltaTime;
                velocity.x = xSpeed * Time.deltaTime;
                if (zSpeed > 0)
                {
                    zSpeed -= acceleration * Time.deltaTime * 2;
                }
                if (zSpeed < 0)
                {
                    zSpeed = 0;
                }
            }
        }
    }
    void regleXSpeed()
    {
        if (xSpeed > 0)
        {
            xSpeed--;
        }
        if (xSpeed < 0)
        {
            xSpeed++;
        }
        if(xSpeed>-1 && xSpeed < 1)
        {
            xSpeed = 0;
        }
    }
}
J'ai une methode run qui s'occupe du déplacement, avec une accéleration et une vitesse max. La vitesse a laquelle j'avance est zSpeed.
J'ai rajouté xSpeed pour avoir mon effet de rebond, pour le moment sur les murs a droite de mon cube l'effet est bon. Sauf a trop grande vitesse d'accord lol.
A gauche j'ai pas encore fait, le contenu est en commentaire actuellement.

Ensuite j'ai une méthode turn qui comme son nom l'indique...

Voila voila, et j'essaie donc d'avoir un système de collision le moins sale possible quoi. Je vous avoue que tout n'est pas maîtrisé parfaitement, je débute et le code est peut-être a vomir pour certains habitués... Tout conseil est bon a prendre en tout cas.

Dans cette vidéo, on peut voir a la fin de la vidéo que le kart se prend un mur :
https://www.youtube.com/watch?v=SlRWVTXfZcU
Je recherche quelque chose de similaire avec un mur un peu plus rebondissant. (Donc pas de voiture qui décolle du sol suite a une collision ect...).

Avatar de l’utilisateur
DevAmat
Messages : 435
Inscription : 23 Nov 2016 11:50

Re: Les collisions et un effet bounce

Message par DevAmat » 28 Avr 2017 16:56

Alors effectivement, utiliser la fonction Translate c'est comme si tu téléportais ton objet a chaque frame. Alors pour moi il y a deux solutions aux quelles je pense direct:

1 - Tu changes ta méthode de déplacement et tu passes par de la physique pure avec ton rigidbody:
https://docs.unity3d.com/ScriptReferenc ... ition.html

2 - Tu gardes ta base mais tu y rajoutes des raycast. A chaque frame tu calcules la futur position de ton objet en tu effectuant un raycast et tu déplace ton objet en conséquence (ou sphere cast etc.) pour anticiper si tu vas heurter le mur. Cet exemple le montre assez bien:
http://answers.unity3d.com/questions/58 ... etect.html

Répondre

Revenir vers « Scripting »