web-dev-qa-db-fra.com

Unity - Le rendement de IEnumerator renvoie null

J'essaie actuellement de comprendre IEnumerator & Coroutine dans le contexte d'Unity et je ne suis pas trop confiant sur ce que le "yield return null" effectue. Pour le moment, je pense que cela fait une pause et attend la trame suivante et dans la trame suivante, il reviendra pour effectuer à nouveau l'instruction while.

Si je laisse de côté le "return return null", il semble que l'objet se déplace instantanément vers sa destination ou peut-être "saute beaucoup d'images". Donc, je suppose que ma question est de savoir comment cette fonction "yield return null" dans cette boucle while et pourquoi est-il nécessaire de l'avoir.

void Start () {
    StartCoroutine(Move());
}

IEnumerator Move(){

    while (a > 0.5f){

        ... (moves object up/down)

        yield return null; // <---------
    }

    yield return new WaitForSeconds(0.5f);

    .... (moves object up/down)

    StartCoroutine(Move());
}
7
WonderfulWonder

Le programme démarrera la boucle, si vous n'aviez pas de rendement, il exécute simplement toutes les itérations dans le même cadre. Si vous aviez des millions d'itérations, cela bloquerait très probablement votre programme jusqu'à ce que toutes les itérations soient terminées, puis continuer.

Lors de la création d'une coroutine, Unity l'attache à un objet MonoBehaviour. Il s'exécutera d'abord sur appel pour StartCoroutine jusqu'à ce qu'un rendement soit atteint. Ensuite, il reviendra de la coroutine et le placera sur une pile en fonction du rendement. Si vous donnez null, alors il s'exécutera à nouveau l'image suivante. Il existe un certain nombre de YieldInstruction différentes qui peuvent être retournées à partir d'une coroutine, vous pouvez en savoir plus à leur sujet ici et via les liens associés .

Une fois qu'une coroutine a cédé, le thread principal continue de fonctionner. Sur la prochaine image, Unity trouvera la coroutine empilée et les appellera d'où ils se sont arrêtés au rendement. Si votre coroutine n'est jamais hors de portée, vous avez essentiellement créé une méthode de mise à jour.

Le but de coroutine est d'effectuer des actions qui pourraient s'étendre sur une période de temps sans bloquer le programme.

FAIT IMPORTANT: ce n'est pas multi-threading.

21
Everts

Vous avez raison. yield return null Attendra jusqu'à la trame suivante, puis poursuivra l'exécution. Dans votre cas, il vérifiera l'état de votre boucle while la prochaine image.

Le "pourquoi c'est nécessaire" est probablement parce que vous voulez que l'objet se déplace par une entrée à chaque image. Sans yield return null, Il exécute simplement la boucle while dans une trame.

Plus essentiel: il semble que vous souhaitiez Update chaque image et ajuster la position. Vous pouvez facilement utiliser la Update () pour cela. Cette fonction sera appelée par Unity chaque image d'un script actif.

4
Max Auer