Atteindre un angle précis avec RotateAround ?

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Duality
Messages : 16
Inscription : 16 Jan 2020 21:01

Atteindre un angle précis avec RotateAround ?

Message par Duality » 27 Mars 2020 13:41

Bonjour,

Je commence à bricoler avec Unity sur une interaction physique simple, en l'occurence une porte.

J'ai donc une porte qui s'ouvre et se ferme quand je suis dans sa zone d'effet et que j’interagis avec elle via une touche du clavier. Je n'utilise pas d'animation mais je passe bien par une rotation physique de ma porte autour d'un axe matérialisé par un Empty.

Ça fonctionne bien mais un truc me chiffonne, l'angle atteint n'est jamais exactement celui qui est désiré (ici 95°) mais toujours un peu plus (95.006° par exemple).

Code : Tout sélectionner

Vector3 EulerAngles = Porte.transform.rotation.eulerAngles;
if (EulerAngles.y < TargetAngle)
            {
                Porte.transform.RotateAround(Pivot.transform.position, Vector3.up, Vitesse * Time.deltaTime );
            } 
Avec Porte étant le mesh de ma porte et Pivot étant le Empty servant d'axe de rotation.

De plus avec ce dépassement, pour fermer ma porte je suis dans l'impossibilité d'écrire ceci :

Code : Tout sélectionner

if (EulerAngles.y > 0)
            {
               Porte.transform.RotateAround(Pivot.transform.position, Vector3.up, -Vitesse * Time.deltaTime );
            }
            
Sans quoi le dépassement fera tourner ma porte à l'infini. A la place je doit écrire cela:

Code : Tout sélectionner

if (EulerAngles.y > 1)
            {
               Porte.transform.RotateAround(Pivot.transform.position, Vector3.up, -Vitesse * Time.deltaTime );
            }
Du coup, Pourquoi mon angle est dépassé et comment remédier à ce problème ?

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

Re: Atteindre un angle précis avec RotateAround ?

Message par boubouk50 » 27 Mars 2020 15:31

Tu ne peux pas comparer des floats. La comparaison se fait avec une approximation.
https://docs.unity3d.com/ScriptReferenc ... ately.html
Aussi, lors de l'ouverture ou fermeture de ta porte une fois un seuil dépassé, tu peux réaffecter ton float.
Par exemple:

Code : Tout sélectionner

Vector3 euler = Porte.transform.rotation.eulerAngles;
if (Porte.transform.rotation.eulerAngles.y > 95f)
{
	euler.y = 95f;
	Porte.transform.rotation.eulerAngles = euler;
}
Ou un truc du genre, pas dit que cela fonctionne.
Attention, il se peut que même en le réaffectant, il reste une approximation et que ton float vaille 95.00001f.
"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

Duality
Messages : 16
Inscription : 16 Jan 2020 21:01

Re: Atteindre un angle précis avec RotateAround ?

Message par Duality » 27 Mars 2020 19:05

Effectivement, petite erreur soulevée par visual studio :
Erreur CS1612 Impossible de modifier la valeur de retour de 'Quaternion.eulerAngles' car il ne s'agit pas d'une variable
PS : Je remarque que le degré d'erreur augmente avec la vitesse d'ouverture/fermeture de la porte.

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

Re: Atteindre un angle précis avec RotateAround ?

Message par djulio74 » 27 Mars 2020 19:15

dans ton script ton erreur n'est est pas une, je mexplique :

Code : Tout sélectionner

if (EulerAngles.y < TargetAngle)
            {
                Porte.transform.RotateAround(Pivot.transform.position, Vector3.up, Vitesse * Time.deltaTime );
            } 
tant que EulerAngles.y < TargetAngle, tu tourne d'un certain degré, defini par vitesse et Time.deltaTime. hors en fonction de la vitesse et de ton reglage du FixedFrameRate, ta valeur d'incrémentation varie.
Imagine Vitesse * Time.deltaTime = 0.11 dans un certain cas hypothétique.
Au debut, EulerAngles.y = 0, puis incrémente de 0.11 pendant 9 itération, et arrive alors a 0.99.
Si targetAngle = 1.0f, alors EulerAngles.y toujours inf a 1.0, donc encore une itération qui t’emmène à 1.1 donc dépassement.
En effet, plus la vitesse augment plus le risque de dépasser de beaucoup est importante, n effet le "pas" est d'autant plus elever.

la solution proposée par boubouk est la bonne. Idéalement mettre ta rotation de porte dans une coroutine, ça éviter a vérifier en continue dans un Update si ta rotation correspond a n valeur voulue.

______________________________________________________________
\_______________________ Impossible is nothing _______________________/

Répondre

Revenir vers « Scripting »