répétition dans une coroutine

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Somoraze
Messages : 207
Inscription : 14 Août 2012 04:09

répétition dans une coroutine

Message par Somoraze » 17 Juil 2013 12:33

Salut,

je n'ai pas bien compris comment utiliser les coroutines pour répéter un code, apparemment il vaut mieux utiliser une coroutine plutôt que l'update: donc j'ai un objet que je fais rebondir doucement en modifiant la valeur du sinus, ça marche bien dans l'update, j'essaie de le mettre dans cette fonction mais il est appelé qu'une fois: sauriez-vous quel est le problème avec InvokeRepeating? Ou quelle est la bonne manière de répéter le code dans la fonction?

Code : Tout sélectionner

IEnumerator startSin() {
	if ( multSin < 0.1f ) {
		//...
	}// < 0.1f		
		
	else if ( multSin > 0 ){
		//...
	}// > 0f
	
	InvokeRepeating("startSin", 0, Time.deltaTime );
	yield return null;
}//#IEnumerator
Merci ;)

Avatar de l’utilisateur
Amethyste
Messages : 136
Inscription : 30 Mai 2013 22:37
Localisation : Vendée

Re: répétition dans une coroutine

Message par Amethyste » 17 Juil 2013 13:26

Salut,

Je n'ai jamais utilisé cette fonction mais un truc me choque

Normalement la fonction que tu veux appelé doit etre en dehors de l'appel

Ensuite le fonctionnement de invoquerepeating est invokerepeating(fonction, tempsavantdepart, tempsavantrepetition)

Donc, logiquement, ton code devrait etre

Code : Tout sélectionner

 InvokeRepeating("startSin", 0, Time.deltaTime );
    IEnumerator startSin() {
       if ( multSin < 0.1f ) {
          //...
       }// < 0.1f      
          
       else if ( multSin > 0 ){
          //...
       }// > 0f
       
       yield return null;
    }//#IEnumerator
Mais, comme je le disait, je n'ai jamais utilisé cette fonction donc il n'est pas sur que ce code fonctionne.

Avatar de l’utilisateur
Shirown
Messages : 20
Inscription : 08 Juil 2013 09:50

Re: répétition dans une coroutine

Message par Shirown » 17 Juil 2013 13:29

Hello ^^

La construction la plus simple pour faire une boucle de Coroutine qui remplace Update() c'est ceci :

Code : Tout sélectionner


    //Method qui lance la coroutine (ici en exemple, Start)
    void Start()
    {
        StartCoroutine("Testing");
    }

    //Coroutine
    IEnumerator Testing()
    {
        //actions dans ta coroutine (faisant office d' Update)
        //(exemple ici comptage des frames)
        Debug.Log(Time.frameCount);

        yield return null;
        RepeatTesting();
    }

    //Method qui répète la coroutine
    void RepeatTesting()
    {
        StartCoroutine("Testing");
    }

J'ai testé vite fait avec InvokeRepeating, c'est pas vraiment adapté pour ça. Ce que tu as fait ne marchait pas car, il veut un string en paramètre et l'IEnumerator se lance avec StartCoroutine.

Mais avec ce que je t'ai donné, tu peux déjà t'amuser à gérer le temps dans le thread ^^.

Avatar de l’utilisateur
cayou66
Codeur
Codeur
Messages : 6450
Inscription : 30 Juin 2011 14:45
Localisation : Montréal

Re: répétition dans une coroutine

Message par cayou66 » 17 Juil 2013 13:53

Code : Tout sélectionner

    //Method qui lance la coroutine (ici en exemple, Start)
    void Start()
    {
        StartCoroutine("Testing");
    }

    //Coroutine
    IEnumerator Testing()
    {
        //actions dans ta coroutine (faisant office d' Update)
        //(exemple ici comptage des frames)
        Debug.Log(Time.frameCount);

        yield return null;
        RepeatTesting();
    }

    //Method qui répète la coroutine
    void RepeatTesting()
    {
        StartCoroutine("Testing");
    }
Qu'on peut transformer en...

Code : Tout sélectionner



    //Method qui lance la coroutine (ici en exemple, Start)
    void Start()
    {
        StartCoroutine("Testing");
    }

    //Coroutine
    IEnumerator Testing()
    {
        while(true)
        {
          //actions dans ta coroutine (faisant office d' Update)
          //(exemple ici comptage des frames)
          Debug.Log(Time.frameCount);

          yield return null;
        }
    }

?

Avatar de l’utilisateur
Shirown
Messages : 20
Inscription : 08 Juil 2013 09:50

Re: répétition dans une coroutine

Message par Shirown » 17 Juil 2013 15:26

Oui Cayou ça donne le même résultat, juste le contrôle qui sera différent. C'est à dire que dans ton algo, c'est une coroutine qui lance une boucle while, la coroutine est lancé une fois. Donc les contrôle de type StopCoroutine ou StopAllCoroutines ne fonctionneront pas. Mais on pourra arrêté ta boucle avec un controle sur le booléen. Donc avoir une variable booléenne pour le paramètre du while fera office de switch (le levier XD).

Ensuite dans mon algo, la method qui refresh peut servir à d'autres choses au moment où la coroutine doit être relancé. Certains contrôles peuvent être fait à ce niveau qui n'ont peut être même rien à voir avec le refresh de la coroutine. Mais un Check quotidien (ou que sais-je) qui doit être fait en plus, avant ou après, le rafraîchissement de la coroutine.

C'est vraiment selon les besoins entre les deux écritures je pense ^^. Et l'habitude aussi. Je sais que je fragmente au mieux mon code en méthodes par exemple.

Mais merci je ne connaissais pas cette structure de code pour ceci :).

Edit : Désolé je mélange les mots anglais et français -__-, je vais essayer de faire un effort.

Avatar de l’utilisateur
artemisart
Messages : 1893
Inscription : 21 Juin 2011 19:51
Localisation : Centre
Contact :

Re: répétition dans une coroutine

Message par artemisart » 17 Juil 2013 15:43

Shirown a écrit :C'est à dire que dans ton algo, c'est une coroutine qui lance une boucle while, la coroutine est lancé une fois. Donc les contrôle de type StopCoroutine ou StopAllCoroutines ne fonctionneront pas.
Euh non pas du tout, une coroutine peut être arrêté dès quelle rencontre un yield return.

En fait, si on veut vraiment comprendre comment ça marche, une coroutine est stoppé dès qu'elle rencontre un yield return, et le mécanisme qui gère les coroutines peut la reprendre quand il veut (voir les classes IEnumerable et IEnumerator).
Shirown a écrit :Ensuite dans mon algo, la method qui refresh peut servir à d'autres choses au moment où la coroutine doit être relancé. Certains contrôles peuvent être fait à ce niveau qui n'ont peut être même rien à voir avec le refresh de la coroutine. Mais un Check quotidien (ou que sais-je) qui doit être fait en plus, avant ou après, le rafraîchissement de la coroutine.
On peut très bien faire les contrôles à l'intérieur de la coroutine (ou en appelant une fonction depuis la coroutine, ce qui revient au même).
Shirown a écrit :

Code : Tout sélectionner


    //Method qui lance la coroutine (ici en exemple, Start)
    void Start()
    {
        StartCoroutine("Testing");
    }

    //Coroutine
    IEnumerator Testing()
    {
        //actions dans ta coroutine (faisant office d' Update)
        //(exemple ici comptage des frames)
        Debug.Log(Time.frameCount);

        yield return null;
        RepeatTesting();
    }

    //Method qui répète la coroutine
    void RepeatTesting()
    {
        StartCoroutine("Testing");
    }

Dans ton code la coroutine sert pas à grand chose vu qu'elle n'exécute rien sur plusieurs frames. Autant appeler la fonction Testing (sans qu'elle soit en coroutine) depuis un Update : plus propre, même résultat, pas d'IEnumerable et IEnumerator alloués.


Pour revenir au premier post :
Somoraze a écrit :je n'ai pas bien compris comment utiliser les coroutines pour répéter un code, apparemment il vaut mieux utiliser une coroutine plutôt que l'update: donc j'ai un objet que je fais rebondir doucement en modifiant la valeur du sinus, ça marche bien dans l'update, j'essaie de le mettre dans cette fonction mais il est appelé qu'une fois: sauriez-vous quel est le problème avec InvokeRepeating? Ou quelle est la bonne manière de répéter le code dans la fonction?

Code : Tout sélectionner

IEnumerator startSin() {
	if ( multSin < 0.1f ) {
		//...
	}// < 0.1f		
		
	else if ( multSin > 0 ){
		//...
	}// > 0f
	
	InvokeRepeating("startSin", 0, Time.deltaTime );
	yield return null;
}//#IEnumerator
Merci ;)
Pourquoi se compliquer la vie ? Un code comme ça a plus ça place dans un Update (en tout cas pour moi). De plus on utilise les coroutines dans le but de répartir une fonction sur plusieurs frames avec yield return, mais le mettre à la fin n'a aucun sens.
InvokeRepeating sert à appeler une fonction (normale, pas coroutine) à intervalles (à peu près) réguliers.
Si tu veux quand même faire du mouvement en coroutine, regarde le deuxième code de cayou, c'est le plus propre (et de loin :mrgreen: ).

Avatar de l’utilisateur
cayou66
Codeur
Codeur
Messages : 6450
Inscription : 30 Juin 2011 14:45
Localisation : Montréal

Re: répétition dans une coroutine

Message par cayou66 » 17 Juil 2013 15:52

Merci arte, tu m'évites bien souvent d'écrire sur ce forum :)

Somoraze
Messages : 207
Inscription : 14 Août 2012 04:09

Re: répétition dans une coroutine

Message par Somoraze » 17 Juil 2013 15:54

Merci, ok c'est bien ce que j'avais essayé au départ avec while, mais il me semblait que ça figeait le jeu, comme si il voulait faire trop de fois la boucle par frame. Mais en effet, je préfère aussi pour cette solution l'update, j'avais simplement lu qu'il fallait plutôt utiliser les coroutines pour une action ponctuelle. Enfin bon, merci de vos réponses ;-)

Avatar de l’utilisateur
artemisart
Messages : 1893
Inscription : 21 Juin 2011 19:51
Localisation : Centre
Contact :

Re: répétition dans une coroutine

Message par artemisart » 17 Juil 2013 15:58

cayou66 a écrit :Merci arte, tu m'évites bien souvent d'écrire sur ce forum :)
De rien :).
Somoraze a écrit :Merci, ok c'est bien ce que j'avais essayé au départ avec while, mais il me semblait que ça figeait le jeu, comme si il voulait faire trop de fois la boucle par frame. Mais en effet, je préfère aussi pour cette solution l'update, j'avais simplement lu qu'il fallait plutôt utiliser les coroutines pour une action ponctuelle. Enfin bon, merci de vos réponses ;-)
Une boucle while "standard" bloque effectivement le jeu (et crash Unity au passage).
Une boucle while avec un yield return à l'intérieur permet de stopper la coroutine et d'en sortir. Le mécanisme gérant les coroutines y reviendra quand nécessaire (frame suivante si on retourne null par exemple).

Avatar de l’utilisateur
Shirown
Messages : 20
Inscription : 08 Juil 2013 09:50

Re: répétition dans une coroutine

Message par Shirown » 17 Juil 2013 20:12

Yop,

Oui effectivement je me suis avancé trop vite, j'ai re-testé tout à l'heure, et la coroutine se stop bien avec StopCoroutine avec le script de Cayou. Désolé pour la confusion ^^. Là prochaine fois je ne testerais pas du code quand je suis sur le départ X'D. J'ai du faire n'imp ^^

Bonne soirée :)

Répondre

Revenir vers « Scripting »