Question

Je suis cette méthode (dans une unité C # Script), mais je ne comprends pas comment la partie « rendement » fonctionne réellement.

Je sais MSDN que la fonction retourne un IEnumerator que je pouvais itérer throught, mais ce code attend 1,5 secondes et ne soit pas Iterated car cela signifierait, les objets créés à l'intérieur ont été créés plusieurs fois. Tout le monde ici qui peut me expliquer comment ce code fonctionne?

IEnumerator DestroyShip()
{
    // create new gameobject
    Instantiate(ExplosionPrefab, transform.position, transform.rotation);
    // make current gameobject invisible
    gameObject.renderer.enabled = false;
    // set new position for the current gameobject
    transform.position = new Vector3(0f, transform.position.y, transform.position.z);
    // wait for 1,5 seconds 
    yield return new WaitForSeconds(1.5f);
    // make the current gameobject visible again
    gameObject.renderer.enabled = true;
}
Était-ce utile?

La solution

Le recenseur le compilateur génère pour vous est itéré. Une fois.

Le compilateur génère une classe qui implémente IEnumerator, qui a une fonction MoveNext () et une propriété actuelle. La classe aura tous les membres requis pour stocker l'état de la fonction entre les appels. Les détails exacts peuvent être considérés comme « Magic compilateur ».

L'objet de cette classe générée, sera traitée et gérée par le Unity3d Engine. Le moteur Unity3d appellera MoveNext () sur chaque coroutine actif une fois toutes les images (sauf indication contraire).

Ceci a permis au programmeur Unity3d aux scripts d'écriture qui sont joués sur une image à la fois. Une combinaison de compilateur C # magie et Unity3d moteur magiques résultats en très-puissant mais facile-à utiliser les scripts.

Pour répondre à votre question. Le code dans votre fonction sera exécutée une fois, mais il fera une pause à la déclaration « yield return »

Comme indiqué ci-dessus, un objet spécial qui implémente IEnumerator est créé par le compilateur C #.

Le premier appel à MoveNext (), votre fonction crée une explosion et définit l'objet en cours de "nouveaux WaitForSeconds (1.5f)".

Le moteur Unity3d inspecte cet objet, voit est une instance de la classe spéciale « WaitForSeconds » met donc le recenseur sur une file d'attente, et ne demandera pas le deuxième élément jusqu'à avoir passé 1,5 sec. En attendant, de nombreux cadres seront rendus et l'explosion seront lus.

Après 1,5 secondes, l'unité sera grap l'énumérateur de la file d'attente et appeler MoveNext () à nouveau. La deuxième partie de votre fonction exécutera maintenant, mais ne parviendra pas à générer un second objet. MoveNext () retourne false pour indiquer qu'il n'a pas réussi à obtenir un nouvel élément, qui est le signal à Unity3d pour lancer cette recenseur loin. Le Garbage Collector va récupérer la mémoire à un moment donné dans le temps.

Comme l'a dit: beaucoup de compilateur et de la magie Unity3d se passe. Tant que vous vous souvenez que votre fonction sera mis en attente jusqu'à ce que la trame suivante à chaque déclaration de retour de rendement, vous saurez assez pour bénéficier de ces fonctions spéciales.

Autres conseils

Si yield est employé une fois, il est comme si vous reveniez un IEnumerator avec un élément, c'est la raison pour laquelle on a l'impression qu'il ne itérer.

Il est un usage assez étrange du mot-clé yield, il est difficile de comprendre pourquoi il a été mis en œuvre sans voir tout le contexte.

Il est préférable de revenir IEnumerable plutôt que IEnumerator car il est plus flaxible et facile à utiliser. Il est même préférable d'utiliser IEnumerable<T>. retour de rendement est tout sucre syntaxique pour mettre en oeuvre un bloc itérateur, le compilateur génère le code relevent car il est essentiellement plaque de chaudière standard qui peut être facilement généré par programmation. Vous utilisez généralement le retour de rendement lorsque vous souhaitez effectuer une série d'actions individuelles apear être une collection, par exemple:.

public IEnumerable<Thing> GetThings()
{
    yield return GetNextThing();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top