[DB] les forces induites après collision

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
Yugo
Messages : 24
Inscription : 12 Nov 2018 15:22

[DB] les forces induites après collision

Message par Yugo » 05 Jan 2019 14:47

Bonjour
Je me demandais comment agir sur les forces induites par une collision entre 2 Rigidbody.
J'ai un vaisseau spatial qui entre en collision avec un astéroïde. Avec des masses corrects les forces de collisions sont réalistes.
Le problème est que je n'arrive pas à reprendre le contrôle du vaisseau après et mon vaisseau tremblote lorsque je lui applique des rotations ou mouvements avec les commandes.
J'utilise addTorque pour les rotations et velocity pour les mouvements.
Je pensais en utilisant cela pouvoir annuler les forces de collision en allant à l'encontre de celle ci grâce au commande du vaisseau mais j'ai l'impression que rien ne les réduit ou les arrête.
Pour l'instant je n'ai trouvez qu'une solution bidouille en appliquant un RigidbodyConstraints.FreezeAll et RigidbodyConstraints.None à la frame suivante mais ça coupe tout d'un coup...pas top.
Comment faire pour arrêter progressivement les forces induites des collisions?

Code : Tout sélectionner

    
    	if (Input.GetKey(KeyCode.Z))
        {
            vaisseauMere.transform.GetComponent<Rigidbody>().velocity += new Vector3(0, 0, 1);
        }
        if (Input.GetKey(KeyCode.S))
        {
            vaisseauMere.transform.GetComponent<Rigidbody>().velocity += new Vector3(0, 0, -1);
        }

        if (( Input.GetAxis("Mouse X") != 0 | Input.GetAxis("Mouse Y") != 0 )
        {
            vaisseauMere.transform.GetComponent<Rigidbody>().AddTorque(vaisseauMere.transform.up * Input.GetAxis("Mouse X"), ForceMode.Acceleration );
            vaisseauMere.transform.GetComponent<Rigidbody>().AddTorque(vaisseauMere.transform.right * -Input.GetAxis("Mouse Y"), ForceMode.Acceleration);

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

Re: [DB] les forces induites après collision

Message par Max » 05 Jan 2019 15:17

Bonjour,
Yugo a écrit :
05 Jan 2019 14:47
Comment faire pour arrêter progressivement les forces induites des collisions?
tu peux passer par une phase rapide de réduction progressive des velocity (RigidBody.velocity et RigidBody.angularVelocity). Après tu peux essayer de jouer sur les Drag par exemple.
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

Avatar de l’utilisateur
Yugo
Messages : 24
Inscription : 12 Nov 2018 15:22

Re: [DB] les forces induites après collision

Message par Yugo » 05 Jan 2019 15:32

Désolé je ne suis qu'un débutant et j'ai du mal à comprendre ta réponse.
comment ca se traduirait en C# ? et qu'est ce que "Drag" ?
ok pour les Drag... sorte de forces de frottement si j'ai bien compris.
mais comment le script peut il savoir si ces forces induites de collision sont encore présentes ?

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

Re: [DB] les forces induites après collision

Message par Max » 05 Jan 2019 17:19

Tu passes par la physique pour gérer ton vaisseau visiblement. Pas simple. A fortiori quand on débute.
Tu utilises la gravité ?
Si je lis bien pour ce qui est des action avancer/reculé, tu ne tiens pas compte de l'orientation de ton vaisseau ?
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

Avatar de l’utilisateur
Yugo
Messages : 24
Inscription : 12 Nov 2018 15:22

Re: [DB] les forces induites après collision

Message par Yugo » 05 Jan 2019 19:40

oui c'est juste un script test.
Je me prend la tête pour faire le pilotage du vaisseau.
Je ne sais pas si je vais pas freeze les rotations et positions du rigidbody et revenir a des rotations de Quaternion.Euler et positionnement par vecteur3 mais ca rend impossible les réactions physiques des collisions pour le vaisseau.
J'aurai voulu, comme dans star wars, qu'un vaisseau dans un couloir de l'etoile de la mort, touche du bout de son aile un morceau de ce couloir et parte en vrille. Le tout si le choc est assez violent.
La j'ai un truc pas top mais ca marche a peu prés :

Code : Tout sélectionner

	if (Input.GetKey(KeyCode.Z))
        {
            vaisseauMere.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezePosition;
            vaisseauMere.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
            vaisseauMere.transform.GetComponent<Rigidbody>().velocity = vaisseauMere.transform.forward*40;
            
        }
        if (Input.GetKey(KeyCode.S))
        {
            vaisseauMere.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezePosition;
            vaisseauMere.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
            vaisseauMere.transform.GetComponent<Rigidbody>().velocity = vaisseauMere.transform.forward*-40;
           

        }

        if (Input.GetAxis("Mouse X") != 0 | Input.GetAxis("Mouse Y") != 0)
        {

    	    vaisseauMere.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotation;
            vaisseauMere.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
            vaisseauMere.transform.GetComponent<Rigidbody>().AddTorque(vaisseauMere.transform.up * Input.GetAxis("Mouse X")*20, ForceMode.Acceleration);
            vaisseauMere.transform.GetComponent<Rigidbody>().AddTorque(vaisseauMere.transform.right * -Input.GetAxis("Mouse Y")*20, ForceMode.Acceleration);

        }
Ca marche quand j'ai une collision et que je ne touche plus aux commandes.
J'imaginais une sorte de coupure des commandes après un choc violent.

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

Re: [DB] les forces induites après collision

Message par Max » 05 Jan 2019 20:06

Oui, 'fin sauf que dans StarWars il s'affranchissent plus que largement des lois de la physique. Et c'est un euphémisme.
A partir du moment où ton objet est lié à ces lois, si ton vaisseau heurte un mur par exemple et part en vrille horizontale, il devient alors bien compliqué d'en reprendre le contrôle. Comme dans la vrai vie si l'on peut dire.
Après, dans l'absolu, ramener tes velocity vers zéro devrait au moins stabiliser ton vaisseau, pour une reprise du contrôle.

PS: quelques remarques sur ton code en passant.
Évites les GetComponent à gogo dans l'update. Récupère le rigidibody de ton vaisseau dans la fonction Start() par exemple, un peu comme

Code : Tout sélectionner

    Rigidbody rbv;

    void Start()
    {
        rbv = vaisseauMere.GetComponent<Rigidbody>();
    }
    
    void FixedUpdate()
    {
         .....
         rvb.AddTorque(...);
         .....
    }    

Sinon, pour tout ce qui est fonction lié à la physique (AddTorque, etc...) fais plutôt appel au callback FixedUpdate(), comme le souligne la doc.
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

Avatar de l’utilisateur
Yugo
Messages : 24
Inscription : 12 Nov 2018 15:22

Re: [DB] les forces induites après collision

Message par Yugo » 06 Jan 2019 01:52

Merci pour ton aide
En effet je pensais mettre dans fixedUpdate une fois avoir trouvé le bon code même si je n'ai pas compris le pourquoi.
Je pense avoir trouvé la solution.
Je Freeze la position et la rotation du RigidBody du vaisseau.
En fonction de la puissance du choc je vais déclencher une perte de contrôle.
Je remet position/rotation du RB pour quelques secondes. Le vaisseau vrille.
Puis je rabaisse les valeurs de velocity en augmentant le Drag jusqu’à les stopper avec un freeze .
Enfin on reprend le contrôle du vaisseau.
Je vais plancher la dessus.
May the force be with you! :-D

Avatar de l’utilisateur
Yugo
Messages : 24
Inscription : 12 Nov 2018 15:22

Re: [DB] les forces induites après collision

Message par Yugo » 06 Jan 2019 01:56

Au faite pourquoi mettre les getComponant en void Start ? Ca prend de la ressource ? il me semblait que c’était juste un chemin d’accès à une variable.

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

Re: [DB] les forces induites après collision

Message par Max » 06 Jan 2019 11:50

Bonjour,

C'est d'abord une histoire d’optimisation tout simplement. Et puis accessoirement, tu obtiens aussi un code plus aéré, plus lisible, ce qui indirectement est aussi un gage de sécurité (limitation des bugs, facilité de relecture, etc...)
Si je reprends ton dernier script, cela donnerait ceci:

Code : Tout sélectionner

    Rigidbody rbv;


    void Start()
    {
        rbv = vaisseauMere.GetComponent<Rigidbody>();
    }

 
    void FixedUpdate()
    {
        if (Input.GetKey(KeyCode.Z))
        {
            rbv.constraints = RigidbodyConstraints.FreezePosition;
            rbv.constraints = RigidbodyConstraints.None;
            rbv.velocity = vaisseauMere.transform.forward * 40;
        }
        if (Input.GetKey(KeyCode.S))
        {
            rbv.constraints = RigidbodyConstraints.FreezePosition;
            rbv.constraints = RigidbodyConstraints.None;
            rbv.velocity = vaisseauMere.transform.forward * -40;
        }

        if (Input.GetAxis("Mouse X") != 0 | Input.GetAxis("Mouse Y") != 0)
        {
            rbv.constraints = RigidbodyConstraints.FreezeRotation;
            rbv.constraints = RigidbodyConstraints.None;
            rbv.AddTorque(vaisseauMere.transform.up * Input.GetAxis("Mouse X") * 20, ForceMode.Acceleration);
            rbv.AddTorque(vaisseauMere.transform.right * -Input.GetAxis("Mouse Y") * 20, ForceMode.Acceleration);

        }
    }

Cette approche pourrait s'appliquer aussi par exemple aux entrées souris, plutôt que de taper des GetAxis("Mouse") dans toutes les lignes. Tout cela s'inscrit dans les pratiques de base à connaitre quand on code.
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

Avatar de l’utilisateur
Yugo
Messages : 24
Inscription : 12 Nov 2018 15:22

Re: [DB] les forces induites après collision

Message par Yugo » 06 Jan 2019 12:49

Ok, merci pour les infos.

Pour l'histoire de freeze les positions et rotations du RB...ben ça ne marche pas évidement.
Si on freeze un RB et qu'il rentre en collision, il ne reçoit pas les forces de collision et donc traverse l'autre RB.
Ce dernier, quant à lui, reçoit les forces et part en vrille.
J'ai trouvé une solution en utilisant un RigidbodyConstraints.FreezeAll dans la Void OncollisionStay.
Dans la void Update je remet RigidbodyConstraints.None.
En gros, à chaque collision j'annule les forces.
Ca marche mais si j'essaye de rentrer dans l’astéroïde j'obtient des mouvements bizarre du vaisseau (saccade, tremblement, changement de direction trop rapide...). normal vu qu'il reçoit des forces antagonistes qui sont annulées après.
Ca m'ira pour mon jeu.
Une dernière question. J'aimerai avoir une valeur de la force d'impact sur mon vaisseau.
Si je fonce dans une boite en carton, cette valeur doit être faible
si je touche un astéroïde à faible vitesse, cette valeur doit être faible aussi.
si je fonce sur un astéroïde, cette valeur doit être élevé.
Je pensais que relativeVelocity.magnitude allait faire le taf mais j'ai la même réaction avec une boite en carton (masse 1) et un astéroïde (masse 10000). Ca ne prend pas en compte les masses ?
il me faudrait une formule pour une variable forceImpact...

Répondre

Revenir vers « Scripting »