[ RESOLU ]déplacement de recttransform "smoothly"

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
UnityNoobUser
Messages : 13
Inscription : 21 Fév 2021 14:54

[ RESOLU ]déplacement de recttransform "smoothly"

Message par UnityNoobUser » 04 Mars 2021 10:37

Salut,

Encore moi ::d

j'aurai besoin d'explication sur un code permettant de modifier la position d'un recttransform de mon canevas de manière douce.

Comme d'hab avec unity pourquoi faire simple alors que cela peux être bien compliqué ;) . j'apprends qu'il n'est pas possible de déplacer un rectransform comme un transform classique et que l'on ne peut donc pas utiliser time.deltatime * facteur.
du coup je regarde sur le net les solution possibles et la solution proposée est d'utiliser une coroutine et .lerp ?!! c'est quoi ça encore 8|

j'utilise le code proposé mais je ne comprend pas bien pourquoi il est nécessaire d'utiliser une coroutine pour faire cela et pour être franc l'intérêt même des coroutines car mon anglais laisse a désirer tout comme les explications claires de la doc unity :langue2:

du coup la coroutine:

Code : Tout sélectionner

IEnumerator LerpCadreInfoPlanetAffichage()
    {
        while (currentTime <= timeOfTravel)
        {
            currentTime += Time.deltaTime;
            normalizedValue = currentTime / timeOfTravel; // we normalize our time
            CadreInfosPlanet.GetComponent<RectTransform>().anchoredPosition = Vector2.Lerp(startCadreInfosPlanetPosition, endCadreInfosPlanetPosition, normalizedValue);
            yield return null;
        }
    }
et la fonction qui sert a afficher mon cadre avec mes textes qui se déclenche lorsqu'un raycast touche certains GameObject

Code : Tout sélectionner

void CadreInfoPlanet()
    {

        if (raycast == true)
        {
               
//la le code pour affecter des valeur aux variables qui servent pour le texte dans mon cadre d'infos puis je lance la coroutine:

            StartCoroutine(LerpCadreInfoPlanetAffichage()); 
            
        }
        else // si le raycast ne touche plus de cible
        {
            //le cadre retourne a sa position initiale
        }
    }
Pourriez vous m'expliquer pourquoi il est nécessaire d'utiliser une coroutine pour faire cela ? pourquoi si j'essai juste avec Vector2.Lerp directement dans ma fonction cela ne fonctionne pas ?

et de plus l'affichage du cadre fonctionne au premier passage de la souris sur l'object mais pas une seconde fois si je vais dans le vide et que je repointe l'objet! je ne comprends pourquoi cette coroutine ne se lance qu'une seule fois .

j'ai également essayé avec Vector3.SmoothDamp mais la le rectransform ne va pas au bon endroit . (lien du code utilisé: //https://answers.unity.com/questions/1 ... sform.html

Pouvez vous m'aider à comprendre tout cela ?
Dernière édition par UnityNoobUser le 05 Mars 2021 12:39, édité 1 fois.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5578
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: déplacement de recttransform "smoothly"

Message par boubouk50 » 04 Mars 2021 14:36

Une coroutine est une fonction qui peut suspendre son exécution.
Ce qui veut dire en gros: tu peux manipuler le temps à l'intérieur.
Donc, l'idée ici, est de gérer le Lerp sur un laps de temps prédéfini.
Pour suspendre l'exécution, tu utilises l'instruction Yield.
Yield return null te permet d'attendre une frame par exemple, donc de continuer le calcul lors de la frame suivante, et ainsi effectuer un Lerp en fonction du temps.
Si tu n'utilises pas la coroutine, alors ton Lerp ne sera calculé que sur une frame donc ton rectTransform passera directement à la position finale.
Aussi le Lerp est linéaire: Lerp = Linear interpolation = interpolation linéaire donc pas de smooth.
Pour avoir un lissage, tu peux lisser l'interpolant avec la fonction SmoothStep.

Un exemple qui pourrait fonctionner je pense:

Code : Tout sélectionner

IEnumerator LerpCadreInfoPlanetAffichage()
    {
    	currentTime = 0f;
    	normalizedValue = 0f;
    	
        while (currentTime <= timeOfTravel)
        {
            currentTime += Time.deltaTime;
            normalizedValue = currentTime / timeOfTravel; // we normalize our time
            CadreInfosPlanet.GetComponent<RectTransform>().anchoredPosition = Vector2.Lerp(startCadreInfosPlanetPosition, endCadreInfosPlanetPosition, Mathf.SmoothStep (0f, 1f, normalizedValue);
            yield return null;
        }
    }
"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

UnityNoobUser
Messages : 13
Inscription : 21 Fév 2021 14:54

Re: déplacement de recttransform "smoothly"

Message par UnityNoobUser » 04 Mars 2021 15:17

pourtant dans la methode lerp il y a dans l'exemple de la doc unity un argument "t" qui est censé définir le nb de frames entre la position A et B. je dois mal interpréter leur exemple :(
public int interpolationFramesCount = 45; // Number of frames to completely interpolate between the 2 positions
dommage je me serais bien passer de la coroutine car je ne suis tjrs pas sur de comprendre comment le yield return null et le lerp permettent de jouer avec les frames :lol:. pour moi cette coroutine dit juste tu fais un déplacement qui se décompose en plusieurs étapes et tu attends une frame.. c'est trop subtile pour moi helas.

a force de relire le code j'interprète juste l'utilisation de la coroutine pour dire a unity: une fonction va être utilisée et durer 5 frames mais le joueur peut continuer a faire quelque chose d'autre en parallèle.

en tous cas je vais suivre ton conseil et tester SmoothStep en plus bien entendu.



et pour le fait que la coroutine ne fonctionne qu'une fois tu aurais une idée sur la cause ?

en tout cas merci aux personnes comme toi qui prennent de leur temps pour partager leurs connaissances sans rien attendre en retour :super: :merci:

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5578
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: déplacement de recttransform "smoothly"

Message par boubouk50 » 04 Mars 2021 18:13

Je ne vais pas te faire un cours sur les fonctions, c'est la base, donc je te conseillerai de faire des cours sur OpenClassRoom (par exemple) pour te mettre à niveau sur la POO C#.

La couroutine est appelée comme une fonction, donc à chaque fois que tu l'appelles:
Ici, elle le sera à chaque fois que CadreInfoPlanet () sera appelée et que raycast sera à True.
Ensuite, elle a son fonctionnement interne. Donc tu l'appelles une fois, puis elle se débrouille pour faire le Lerp en X frames.

Aussi, tu me colles des bribes de ton script, et ensuite tu viens me parler d'une variable interpolationFramesCount inconnue. Je ne suis pas devin, mais je devine que le Lerp s'effectue donc en 45 frames. Ca fixe donc le temps de l'interpolation. Si tu veux faire pareil dans la coroutine, c'est possible. Il suffit d'incrémenter l'interpolant par 1/45 à chaque boucle.
Il faut comprendre le principe de boucle et d'Update () pour comprendre l'ordre d'exécution du code et sa temporalité.

Je sens que tu patauges dans tout ça, et c'est uniquement parce que tu n'as pas encore les bases de la programmation. Bidouiller, c'est rigolo au début et super quand ça fonctionne rapidement pour des petits trucs, mais pour faire un jeu, c'est plutôt la galère. Sans les bases pour comprendre, tu vas y passer un temps et des efforts incroyables.
Tout ceci peut être rapidement éviter en commençant par le commencement: Apprendre les bases de la programmation.
Tu te mettras à comprendre ce que tu fais, à comprendre la doc, à comprendre ce que font les autres (pour mieux les copier) et te faciliteras la vie. Et tu te poseras aussi les bonnes questions, et tu nous les poseras également. C'est gagnant à tous les coups.
"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

UnityNoobUser
Messages : 13
Inscription : 21 Fév 2021 14:54

Re: déplacement de recttransform "smoothly"

Message par UnityNoobUser » 04 Mars 2021 19:19

oui je débute sur unity et le langage c# et je n'avais pas l'intention de me pencher sur les coroutines de suite pour apprendre avec mon petit jeux mais comme je me suis dit que ça serait plus sympa si mon cadre s'affichait plus doucement et qu'unity ne permet pas un déplacement des recttransform selon le même principe que les transform j'ai tenté l’expérience mais me casse un peu les dents car comme tu le dis pas encore assez d’expérience...après c'est en tombant que l'on apprend a marcher puis à courir ^^

le bout de code que j'ai mis dans mon message précédent n'est pas dans mon code mais dans celui de l'exemple fournit par la doc unity de .lerp et c'est celui ci qui , a l'origine, m'a fait penser que cela permettait de faire ce que je voulais.

concernant le fait que la coroutine ne s’exécute qu'une fois en revanche je ne comprend tjrs pas pourquoi car la fonction CadreInfoPlanet () est appelé en permanence puisque s’exécute dans void Update() et la condition raycast à True est vrai puis que le fait d'enlever le pointeur de la souris d'un des gameobject passe la variable à "false" et le remettre la re définie en "true" (verifier avec des debug.log et le code avant l'appel de la coroutine s’exécute aussi correctement sans prb autant de fois que je passe et repasse sur mes objets.) c'est pour régler ce prb que je m'acharne a essayer de comprendre le code de la coroutine que j'ai copier depuis la page web car je pensai que le prb venait de ce coin la et pas de ma fonction CadreInfoPlanet ()
Dernière édition par UnityNoobUser le 05 Mars 2021 12:58, édité 3 fois.

UnityNoobUser
Messages : 13
Inscription : 21 Fév 2021 14:54

Re: déplacement de recttransform "smoothly"

Message par UnityNoobUser » 05 Mars 2021 09:41

Vous pouvez mettre en résolu (je sais pas si je peux le faire)

on est le matin et mon cerveau c'est remis en route. la boucle while de la coroutine ne se re exécutait pas car la variable "current" passait et restait légèrement à 5 (enfin un peu plus) apres la première utilisation. du coup je réinitialise a 0 sa valeur avant de faire de nouveau appel a LerpCadreInfoPlanet() et cela fonctionne.

bonne journée

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5578
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: déplacement de recttransform "smoothly"

Message par boubouk50 » 05 Mars 2021 10:13

Si tu avais fait attention au code que j'ai posté à la première réponse, tu aurais vu que je réinitialisais les variables.

Pour passer un sujet en résolu, il te suffit d'éditer le premier message et d'ajouter [RESOLU] au début du titre.
Je m'en occupe cette fois-ci.

Bon dev.
"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

Répondre

Revenir vers « Scripting »