[RESOLU][DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
Avatar de l’utilisateur
Wydman
Messages : 7
Inscription : 31 Jan 2017 14:28

[RESOLU][DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Wydman » 31 Jan 2017 17:10

Bonjour à toutes et à tous,
Alors je viens ici car j'ai un petit truc avec lequel je galère un peu,
Désolé par avance si j'ai un peu de mal à être clair, je vais faire de mon mieux.

En gros, j'ai un jeu en fausse 2D vue de profil ( un peu comme un shmup) dans lequel le player se ballade sur un axe X et Y. sachant que j'utilise un prefab de controller android avec un joystick pour la gestion de la vitesse (grâce à un AddRelativeForce) et sa direction (grâce à un transform.eulerAngles lié a la direction du joystick )

Voila jusque là tout va bien !
L'idée maintenant c'est lorsque je double tap sur l'ecran je crée un empty qui me renvois des coordonées, tout mon problème réside sur le fait que j'aimerais dynamiquement et en douceur faire en sorte que ma petite fusée se mette en rotation autour de se point ( sur un axe fixe car en 2D )avec une trajectoire lisse et surtout en conservant sa vitesse, Sa vitesse qui va du coup proportionnellement modifier la taille de l'orbite autour du point( je rajouterais un slider pour modifier la vitesse et donc le rayon de l'orbite dans se mode de contrôles). puis enfin Pinacle de la chose, j'aimerais que la vitesse de sortie de ce mode ( lorsque l'on double tap a nouveau) soit effective et directionnelle.

La vache c'est pas clair :s


J'ai essayé d'utiliser "transform.RotateAround" mais mon object prend des trajectoires bizarres avant de se positionner en rotation, puis je n'arrive pas à récupérer sa vélocité en fin mode de rotation.

j'ai ce matin testé de jouer sur le Torque mais je n'en ai rien sortis de concret.

Evidemment je me tiens prêt a vous donner des précisions et je m'excuse encore si le tout vous semble confus.

Merci d'avance.
Dernière édition par Wydman le 22 Fév 2017 03:12, édité 1 fois.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6216
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par boubouk50 » 31 Jan 2017 17:19

Salut,

Je ne pense pas qu'utiliser Transform.RotateAround () soit une bonne solution puisqu'elle n'utilise pas la physique alors que ta fusée oui. Comme je le verrai, je te dirai d'interpoler la direction de ta fusée avec un vecteur tangent à ton point en fonction de cette même direction puis d'utiliser les AddForce (). Tu pourrais aussi calculer l'angle entre ta direction et le vecteur Fusée-Centre (donc dotProduct), si cet angle vaut 90° (et suffisamment proche?) alors ta fusée se met en orbite. Une fois dans l'orbite, calculer le nouveau vecteur tangent uniquement pour déplacer ta fusée. Enfin, pour décrocher tu ne calcules plus rien, ta fusée reste dans sa trajectoire.
Si tu vois ce que je veux dire.

Si tu as une illustration ou une démo vidéo de ce que tu veux faire exactement, ce serait mieux. Le comportement de ta fusée est plus complexe que cela normalement (en fonction de la distance du point donc de l'attraction ou répulsion, etc)
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
Wydman
Messages : 7
Inscription : 31 Jan 2017 14:28

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Wydman » 31 Jan 2017 17:37

Tout d'abord, Merci de ta réponse,

Alors oui ,sur le papier je vois ce que tu veux dire, et c'est même à peu de choses près l'idée que je m'en faisais, malheureusement j'avoue que la mise en place de ce vecteur tangent entre mon point de rotation et ma fusée me dépasse un peu, pour moi la trigonométrie ça remonte un peu à loin ^^.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6216
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par boubouk50 » 31 Jan 2017 17:40

Je viens d'éditer ma 1e réponse. (J'ai un peu plus étoffer ma réponse)

Le vecteur tangent, surtout en 2D, est très simple à trouver puisqu'à 90° du vecteur Fusée-CentreDeGravité, il faut déterminer lequel des 2, devant ou derrière (facile, y'en a un positif, l'autre négatif). (Voir DotProduct / Vecteur colinéaire)
Je ne me fais pas de souci pour que tu trouves sur le net.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Avatar de l’utilisateur
Wydman
Messages : 7
Inscription : 31 Jan 2017 14:28

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Wydman » 02 Fév 2017 20:56

Me voici à nouveau, et malgré ton aide je dois dire que je n'ai pas beaucoup avancé, j'imagine que ça doit paraître ridicule pour quelqu'un ayant un minimum de bagage, mais j'ai beaucoup de mal à synthétiser mon idée de la rotation de la fusée autour de son axe, et vu que c'est le core-gameplay du jeu je veux que ce soit parfait.

En fait je réussi a faire tourner ma fusée autour de mon point, mais sans vélocité d'origine, si elle est en mouvement ça deviens le bordel, En fait je n'ai aucune idée de comment forcer la trajectoire de ma fusée tout en gardant Et en modifiant sa vélocité. De plus j'aimerais que le diamètre du cercle de rotation soit modifiable en plus de la vitesse.

En plus de ça j'aimerais que ma fusée soit toujours parallèle a la tangente du cercle, et c'est la même chose, le concept me va, je visualise bien la chose, mais le mettre en place est une tout autre histoire... et j'avoue que ça me frustre car j'imagine que ça n'a rien de bien compliqué.


concrètement voila mon objectif, en plus mon jeu est en 2D donc la représentation est plutôt exacte( en oubliant le fait que je suis nul sur Paint).
Image


j'ai essayé de trifouiller avec le DotProduct, ou le CrossProduct de mes vecteurs, mais je suis tellement perdu dans mes vecteurs que j'ai du mal à savoir ce que je dois calculer et avec quelles informations.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6216
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par boubouk50 » 03 Fév 2017 10:25

As-tu fait les Unity Learn sur la physique? Certaines composantes de la physique intégrée devraient te donner des idées. Notamment les distance joints et les point effectors.
https://unity3d.com/fr/learn/tutorials/ ... e-joint-2d
Tu as la liste à droite. C'est en anglais mais on te montre tout donc pas forcément besoin de son si tu n'es pas bilingue.

Concernant le code, c'est de la géométrie et l'application de propriétés connues. Après c'est comme tout, c'est pas inné. Donc, c'est normal que tu te sentes un peu perdu, faut se (re)mettre dans le bain!

Tu ne dois pas "trifouiller" le dotProduct (je sais même pas comment on le trifouille, faut appeler 3 policiers? :arrow: ok, je sors...), il te permet de connaître la colinéarité de 2 vecteurs, donc leur parallélisme ou leur perpendicularité, et leur sens. Il sert de condition. Après tout est question de calcul vecteur directionnel.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Moi 1971
Messages : 727
Inscription : 29 Sep 2015 13:38

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Moi 1971 » 03 Fév 2017 10:58

Bonjour,
pour t'aider au niveau des maths, il faudrait que nous dire avec quel méthode tu déplace ta fusée.
Déplacement avec le transforme ou avec des AddForce()?

(Pas envie de surcharger en messages...) EDIT Boubouk: J'ajouterai aussi, vu qu'on est dans la section code, que tu pourrais le poster, qu'on se fasse une idée.

Avatar de l’utilisateur
Wydman
Messages : 7
Inscription : 31 Jan 2017 14:28

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Wydman » 03 Fév 2017 19:35

Alors tout d'abord, merci pour votre temps,
Je découvre Unity Learn en ce moment, c'est juste génial ! et j'ai la chance de ne pas avoir de soucis en anglais ^^.
Alors pour les Distance Joint2D j'ai un problème, c'est qu'il requiert un RigidBody2D et mon player est en RigidBody
(Même si le jeu fonctionne en 2D j'ai besoin de la 3D pour certain plans ( zoom sur le modèle du vaisseau, Docking, rotation sur le menu du jeu etc...)

Du coup je me demande si ça ne poserais pas de soucis d'utiliser une méthode 2D dans un jeu 3D même si le contexte d'utilisation reste 2D.

pour ce qui est du DotProduct, je dit avoir trifouiller, dans le sens ou j'ai réussi à l'utiliser pour savoir si mon point de rotation était devant/ à gauche / à droite ou derrière ma fusée, mais je n'ai pas eu l'idée de l'utiliser en condition, Après, c'est toujours le même soucis, avec un transform et un CrossProduct j'ai réussi a avoir une courbe plutôt pas mal suivis d'une bonne rotation autour du point, mais ça me coupe ma vélocité. du coup je veux utiliser un AddForce, mais comment cantonner ma trajectoire à une orbite donnée, aucune idée... car imaginons :

je met en condition la colinéarité de mes 2 vecteurs, et j'ajoute une force que lorsque mes vecteurs sont bien alignés, comment je fais pour que mes 2 vecteurs restent bien alignés ?, je ne comprends pas comment coller ma fusée à sa trajectoire durant la rotation, et comment lui donner une courbe fluide vers sa rotation avant cela.

Enfin, "Moi 1971" j'utilise un AddRelativeForce (), mais je l'avais bien précisé dans mon premier post.

et pour le code, sur la partie mouvement de ma fusée voici ce que j'utilise :

pour la gestion de la vitesse :

Code : Tout sélectionner


public float speed2, ajustSpeed;

float h = CrossPlatformInputManager.GetAxis("Horizontal");
float v = CrossPlatformInputManager.GetAxis("Vertical");
if (v >= 0) { ajustSpeed = v; } else { ajustSpeed = -v; }
GetComponent<Rigidbody>().AddRelativeForce(new Vector3(0, speed2 * ajustSpeed, 0) * Time.deltaTime);
pour l'inclinaison par rapport à mon joystick :
(j'ai trouvé ça et j'avoue ne pas avoir trop idée de comment ça fonctionne( à part le fait que ça calcule la tangente de "h" et "v" me sort un résultat en radiant et est convertit en degrés mais j'imagine que me plonger dans Unity Learn va m'aider)

Code : Tout sélectionner

transform.eulerAngles = new Vector3(Mathf.Atan2(h, v) * Mathf.Rad2Deg, 90, 0);

bon et pour mon second système de contrôle je n'ai rien à pars ma condition d'entrée dans ce mode et mon déplacement en Transform.Translate() temporaire obsolète . d'où ma détresse ^^

Moi 1971
Messages : 727
Inscription : 29 Sep 2015 13:38

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Moi 1971 » 03 Fév 2017 22:33

Pour déplacer un "Objet" avec Unity, il y a deux façons de faire.
-Soit avec les transform.Translate() qui déplacent arbitrairement d'un point à un autre. (c'est pas ce que tu semble vouloir faire)
-Soit en utilisant la physique d'Unity avec les AddForce().
Il ne faut pas utiliser les deux en même temps. Donc il te faut choisir une méthode et ensuite trouver le moyen de réaliser ce que tu veux faire.
Avec la deuxième méthode, la vélocité ne doit pas être modifiée (sauf à l'initialisation pour réaliser un "coup de canon"), il faut l'utiliser en lecture pour par exemple atteindre une vitesse limite : TANT QUE velocity < X ALORS AddForce().
Tu gères déjà la vitesse de déplacement (ajustSpeed) mais la force que tu appliques est toujours le même vecteur (ajustSpeed) C'est la magnitude de ce vecteur que tu changes. La force que tu appliques a ton objet doit le "pousser" là où tu veux le diriger. Donc il te faut calculer avant les coordonnées x,y et z du point "target" et calculer le vecteur directionnel entre le centre de ton objet et le "target". Il faut ensuite normaliser ce vecteur et l'utiliser en le multipliant par "ajustSpeed" dans ton AddForce().
Est-ce que c'est ce que tu veux faire?

Avatar de l’utilisateur
Wydman
Messages : 7
Inscription : 31 Jan 2017 14:28

Re: [DB-AL] Gestion d'inertie et de rotation entre 2 GameObject

Message par Wydman » 22 Fév 2017 03:12

Tout d'abords merci à tous pour votre aide, je suis désolé de revenir vers vous si tard, j'ai eu la chance de partir en vacance et le redémarrage a été un peu long.

j'envois la solution que j'ai décidé d'adopter.
j'ai trouvé le noyau dur du code et je l'ai adapté en fonction de mes besoins. Ce qu'il me manquait en fait était ce second vecteur me rapprochant de la cible, une fois en place je l'ai rendu égal au premier vecteur tangent pour obtenir une "orbite" stable et modifiable via un Slider ajouté, qui gère donc la vitesse et la taille de l'orbite proportionnellement(je garde pour l'instant les deux valeurs du slider pour peut être plus tard permettre des ellipses autour de la Target.

J'ai de plus ajouté la condition sur la vélocité ( merci beaucoup "Moi 1971"), il me reste quelques problèmes avec la condition du drag qui fais un peu n'importe quoi mais vu que ces conditions ne sont peut être pas permanentes, je m'en suis un peu désintéressé.

Alors si vous voyez des trucs complètement aberrant n’hésitez pas ! mais avec le résultat actuel satisfaisant, je passe le sujet en résolu :)

Code : Tout sélectionner

   
   
        distance = GameObject.Find("SliderDistance").GetComponent<Slider>();
        vitesse = GameObject.Find("SliderDistance").GetComponent<Slider>();

        distanceTarget = distance.value;
        speedTarget = vitesse.value;



        velocity = GetComponent<Rigidbody>().velocity.magnitude;
   
   
   
   
   
   
	target = GetComponent<focusController>().rotationPointTransform;
	forward = transform.TransformDirection(Vector3.back); 
	dir = target.transform.position - transform.position; 
	side = Vector3.Cross(dir, forward);



            if (velocity < speedTarget)
            {
                GetComponent<Rigidbody>().drag = 0f;
                GetComponent<Rigidbody>().AddForce(dir.normalized * distanceTarget *100* Time.deltaTime);
                cross = Vector3.Cross(dir, side); 
                GetComponent<Rigidbody>().AddForce(cross.normalized * speedTarget *100* Time.deltaTime); 

            }

            else if (velocity > speedTarget)
            {
                GetComponent<Rigidbody>().drag = 2f;
            }
            else
            {
                GetComponent<Rigidbody>().drag = 0f;
            }
            
            transform.LookAt(player.GetComponent<focusController>().positionPointVector);
            
            

Répondre

Revenir vers « (C#) CSharp »