Inhaltsverzeichnis
1. Vorwort:
Coroutinen sind ein sehr wichtiges Konzept in Unity. Wir wissen, dass Multithreading im Allgemeinen nicht berücksichtigt wird (beachten Sie, dass dies im Allgemeinen der Fall ist). werden zur Verfügung gestellt.
Warum wird Multithreading in Unity generell nicht berücksichtigt?
Da in Unity die Komponenten, Methoden und Objekte von Objekten nur im Hauptthread abgerufen werden können, können viele Funktionen von Unity nicht realisiert werden, sodass die Existenz von Multithreading von geringer Bedeutung ist.
Was ist der Unterschied zwischen Threads und Coroutinen?
Bei Coroutinen kann nur eine Coroutine gleichzeitig ausgeführt werden, während Threads gleichzeitig ausgeführt werden können und mehrere Threads gleichzeitig ausgeführt werden können.
Die gemeinsame Nutzung des Heaps und die Nichtfreigabe des Stapels
ist tatsächlich am vorteilhaftesten Für beide ist der einfachste Unterschied, dass Threads mikroskopisch parallel sind (für Multi-Core-CPUs), während Coroutinen seriell sind. Wenn Sie es nicht verstehen, werden Sie es verstehen
2. Über Coroutinen
1. Was ist eine Coroutine?
Coroutine bedeutet wörtlich: „Hilfsprogramm“ Während die Hauptaufgabe ausgeführt wird, müssen wir einige Zweigaufgaben zusammenarbeiten, um den endgültigen Effekt zu erzielen. Stellen Sie sich vor, dass wir bei der Ausführung der Hauptaufgabe sind Wir benötigen eine Operation, die viele Ressourcen verbraucht. Wenn wir eine solche Operation in einem Frame implementieren, wird das Spiel sehr verzögert. Zu diesem Zeitpunkt können wir die Verarbeitung der Arbeit innerhalb eines bestimmten Frames abschließen Auswirkungen auf den Fortschritt der Hauptaufgabe haben.
2. Prinzip der Coroutine
Zunächst müssen Sie verstehen, dass Coroutinen immer noch im Hauptthread ausgeführt werden. Anschließend müssen Sie wissen, dass Coroutinen Funktionen über Iteratoren implementieren. Beachten Sie, dass Sie IEnumerator verwenden anstelle von IEnumerable.
Der Unterschied zwischen den beiden:
IEnumerator: ist eine Schnittstelle, die die Iteratorfunktion implementiert.
Es gibt eine GetEnumerator()-Methode, die IEnumerator
im Iterator zurückgibt . Dies ist die Hauptmethode, um die Funktion unserer Coroutine zu realisieren. Mit dieser Schlüsselmethode können wir die Ausführung der Coroutine anhalten, die Zeit und den Ort des nächsten Starts aufzeichnen.
Eine detaillierte Beschreibung von Iteratoren finden Sie in der offiziellen C#-Dokumentation für eine detaillierte Beschreibung von Iteratoren .
3. Verwendung von Coroutinen
Missverständnis:
Wenn eine Coroutine fast jeden Frame ausführt und bei lang laufenden Vorgängen nicht pausiert, ist es normalerweise sinnvoller, die Coroutine durch einen Update- oder LateUpdate-Callback zu ersetzen. Zum Beispiel Coroutinen mit langer Laufzeit oder Endlosschleifen.
Reduzieren Sie die Verwendung von Verschachtelungen so weit wie möglich: Obwohl verschachtelte Coroutinen sehr hilfreich sind, um die Organisation und Wartung des Codes sicherzustellen, führt das Coroutine-Tracking-Objekt selbst zu einem höheren Speicheraufwand.
1. Funktioneller Ansatz
Verwenden Sie die Übertragungsfunktion, um die Coroutine zu starten:
StartCoroutine(Cor_1());
Stoppen Sie die Coroutine: (❎ Falsche Verwendung 1)
StopCoroutine(Cor_1());
Ich habe das gemacht, als ich es zum ersten Mal gelernt habe, aber ich weiß nicht, warum es einfach nicht funktioniert hat. Später wurde mir klar: Obwohl derselbe Funktionsname übergeben wurde, war die Adresse der Funktion, die beim Stoppen übergeben wurde, nicht die Adresse der Funktion, die am Anfang übergeben wurde ~.
Stoppen Sie die Coroutine: (❎ Falsche Verwendung 2)
StopCoroutine(”Cor_1“);
Falsche Verwendung für Neulinge: Verwenden Sie die Methode der Übergabe einer Funktion, um die Coroutine zu starten, und die Methode der Übergabe einer Zeichenfolge, um die Coroutine zu stoppen.
Wenn Sie also StartCoroutine(Cor_1()); verwenden, um die Coroutine zu starten, wie können Sie sie manuell stoppen? Bitte lesen Sie weiter…
2. Die Methode des Funktionsnamens
Starten Sie die Coroutine, indem Sie den Funktionsnamen übergeben:
StartCoroutine("Cor_1");
Stoppen Sie die Coroutine:
StopCoroutine(”Cor_1“);
Es ist kein Problem, es auf diese Weise zu verwenden (ich vermute, die interne Implementierung speichert es in der Form <Key, Value>).
Nachteile: Unterstützt nur die Übergabe eines Parameters.
Aus 1 und 2 können wir schließen, dass nur das Öffnen und Schließen in Form von Funktionsnamen möglich ist, dies löst jedoch nicht die in unserer Methode 1 verbliebenen Probleme. Bitte lesen Sie weiter ...
3. Rückgabewert erhalten
Unabhängig davon, welche der folgenden Methoden zum Starten der Coroutine verwendet wird, können Sie ihren Rückgabewert beenden, um die entsprechende Coroutine zu stoppen.
private Coroutine stopCor_1;
private Coroutine stopCor_2;
stopCor_1 = StartCoroutine("Cor_1");
stopCor_2 = StartCoroutine(Cor_2());
Stoppen Sie die Coroutine:
StopCoroutine(stopCor_1);
StopCoroutine(stopCor_2);
Mit dieser Methode zum Empfangen von Rückgabewerten können wir die Coroutine entsprechend unseren Anforderungen stoppen.
Dadurch werden die in den Methoden eins und zwei verbleibenden Probleme gelöst.
4. Stoppen Sie alle Coroutinen
Starten Sie die Coroutine auf irgendeine Weise
StartCoroutine("Cor_1");
StartCoroutine(Cor_2());
Sie können StopAllCoroutines zum Stoppen verwenden
StopAllCoroutines();
StopAllCoroutines() kann alle Coroutinen im aktuellen Skript stoppen.
Zu beachten:
Es wird empfohlen, es mit Vorsicht zu verwenden, da es möglich ist, beim späteren Ändern der Logik eine neue Coroutine zu erstellen und diese zu stoppen, ohne dass sie gestoppt wird (fragen Sie mich nicht, woher ich das weiß).
Sie müssen sicherstellen, dass alle Coroutinen das tun Aufruf des Skripts muss beendet werden (z. B. trennen und erneut verbinden) Alle Status müssen zurückgesetzt werden)
5. Spielobjekte deaktivieren/zerstören
Das Deaktivieren/Zerstören der Spielobjekt-Coroutine wird beendet. Wenn das Objekt erneut aktiviert wird, setzt die Coroutine die Ausführung nicht fort.
gameObject.SetActive(false);
//通过销毁游戏对象方式和禁用同效果
//Destroy(gameobject)
Das ist es nicht:
script.enabled = false;
Das heißt, das vom versteckten Skript bereitgestellte Spielobjekt (dasselbe gilt, wenn das übergeordnete Objekt ausgeblendet ist).
6. Einführung in die Rendite:
yield return null; // 下一帧再执行后续代码
yield return 0; //下一帧再执行后续代码
yield return 6;//(任意数字) 下一帧再执行后续代码
yield break; //直接结束该协程的后续操作
yield return asyncOperation;//等异步操作结束后再执行后续代码
yield return StartCoroution(/*某个协程*/);//等待某个协程执行完毕后再执行后续代码
yield return WWW();//等待WWW操作完成后再执行后续代码
yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行
yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响);
yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响);
yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码
yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候....如:yield return new WaitUntil(() => frame >= 10);
yield return new WaitWhile()//将协同执行直到 当输入的参数(或者委托)为false的时候.... 如:yield return new WaitWhile(() => frame < 10);
4. Zusammenfassung:
- Wenn es mit StartCoroutine(function()); gestartet wird, kann es nur durch den Empfang des Rückgabewerts gestoppt werden; [Keine Begrenzung der Parameteranzahl]
- Wenn es mit der Form StartCoroutine("function name"); gestartet wird, kann es mit der Form StopCoroutine("function name"); gestoppt werden, oder es kann durch den Empfang des Rückgabewerts gestoppt werden. [Nachteil: Es kann nur ein Parameter übergeben werden]
- Beide Öffnungsformen werden von StopAllCoroutines() gesteuert. StopAllCoroutines() kann alle Coroutinen im aktuellen Skript stoppen.
- gameObject.SetActive(false); kann alle Coroutinen auf diesem GameObject stoppen und die Coroutinen werden nicht fortgesetzt, wenn sie erneut aktiviert werden.
- StopCoroutine(function()); script.enabled = false; Die Coroutine kann nicht gestoppt werden.
5. Dinge, die Sie beachten sollten
Coroutinen sollten in tatsächlichen Projekten mit Vorsicht verwendet werden, da die Verwendung von Coroutinen die Leistung beeinträchtigt.