目次
一、前言:
コルーチンは Unity の非常に重要な概念です。ゲーム開発に Unity を使用する場合、通常はマルチスレッドが考慮されないことはわかっています (一般的に考慮されていることに注意してください)。それでは、Unity が提供する主要なタスク以外の要件にどのように対処すればよいでしょうか。が提供されます。
Unity ではマルチスレッドが一般的に考慮されていないのはなぜですか?
Unityではオブジェクトのコンポーネントやメソッド、オブジェクトはメインスレッドでしか取得できないため、これらが分離されてしまうとUnityの多くの機能が実現できなくなるため、マルチスレッドの存在はあまり意味がありません。
スレッドとコルーチンの違いは何ですか?
コルーチンの場合、同時に実行できるコルーチンは 1 つだけですが、スレッドは同時に実行でき、スタックを
共有せずにヒープを共有すること
が実際に最も有益です。どちらも重要で、最も単純な違いは、微細に見るとスレッドは並列であるのに対し、コルーチンはシリアルであるということです。理解していなくても問題ありません。
2. コルーチンについて
1. コルーチンとは何ですか?
コルーチンは文字通り、メイン タスクの実行中に、最終的な効果を達成するためにいくつかのブランチ タスクが連携する必要があることをもう少しわかりやすく説明します。大量のリソースを消費する操作が必要ですが、そのような操作を 1 つのフレーム内で実装すると、ゲームは非常に遅くなります。このとき、コルーチンを使用して、特定のフレーム内で処理を完了することができます。メインタスクの進行には影響しません。
2. コルーチンの原理
まず、コルーチンはスレッドではないことを理解する必要があります。次に、コルーチンは反復メソッドを使用して関数を実装することを理解する必要があります。 IEnumerable の代わりに。
2 つの違いは次のとおりです。
IEnumerator: イテレータ関数を実装するインターフェイスです。
IEnumerable: IEnumerator に基づくカプセル化されたインターフェイスです。
最も重要なことは、イテレータで IEnumerator を返すことです。 、これはコルーチンの機能を実現する主な方法であり、このキー メソッドを通じて、コルーチンの実行を一時停止したり、次の起動の時刻と場所を記録したりできます。
イテレータの詳細な説明については、C# 公式ドキュメントのイテレータの詳細な説明を参照してください。
3. コルーチンの使用
誤解:
コルーチンがほぼすべてのフレームで実行され、長時間実行される操作中に一時停止しない場合は、通常、コルーチンを Update または LateUpdate コールバックに置き換える方が合理的です。たとえば、長時間実行または無限ループのコルーチンです。
ネストの使用をできる限り減らす: ネストされたコルーチンは、コードの編成とメンテナンスを確実にするのに非常に役立ちますが、オブジェクトを追跡するコルーチン自体によりメモリ オーバーヘッドが高くなります。
1. 機能的アプローチ
伝達関数を使用してコルーチンを開始します。
StartCoroutine(Cor_1());
コルーチンを停止します: (❎ 間違った使用法 1)
StopCoroutine(Cor_1());
初めて習ったときはそうしましたが、なぜうまくいかなかったのかわかりません。後で気づいたのですが、同じ関数名を渡しているのに、停止時に渡した関数のアドレスが、最初に渡した関数のアドレスではありませんでした~。
コルーチンを停止します: (❎ 間違った使用法 2)
StopCoroutine(”Cor_1“);
初心者向けの間違った使い方: コルーチンを開始するには関数を渡す方法を使用し、コルーチンを停止するには文字列を渡す方法を使用します。
それでは、StartCoroutine(Cor_1()); を使用してコルーチンを開始する場合、どうすれば手動で停止できるでしょうか?続きをお読みください…
2. 関数名の付け方
関数名を渡してコルーチンを開始します。
StartCoroutine("Cor_1");
コルーチンを停止します。
StopCoroutine(”Cor_1“);
このように使用しても問題はありません (内部実装では <Key, Value> の形式で保存されていると思います)。
短所: 1 つのパラメータの受け渡しのみをサポートします。
1 と 2 から、関数名の形式でのオープンとクローズのみが実行可能であると結論付けることができますが、これでは方法 1 に残された問題は解決されません。 続きを読んでください...
3. 戻り値を受け取る
コルーチンの開始に次のメソッドのいずれを使用しても、その戻り値を終了して、対応するコルーチンを停止できます。
private Coroutine stopCor_1;
private Coroutine stopCor_2;
stopCor_1 = StartCoroutine("Cor_1");
stopCor_2 = StartCoroutine(Cor_2());
コルーチンを停止します。
StopCoroutine(stopCor_1);
StopCoroutine(stopCor_2);
戻り値を受け取るこのメソッドを使用すると、必要に応じてコルーチンを停止できます。
これにより、メソッド 1 と 2 で残された問題が解決されます。
4、すべてのコルーチンを停止する
何らかの方法でコルーチンを開始する
StartCoroutine("Cor_1");
StartCoroutine(Cor_2());
StopAllCoroutines を使用して停止できます
StopAllCoroutines();
StopAllCoroutines() は、現在のスクリプト内のすべてのコルーチンを停止できます。
注意すべき点:
後でロジックを変更するときに新しいコルーチンを作成し、停止せずに停止する可能性があるため、注意して使用することをお勧めします (どうやって知っているかは聞かないでください)
。スクリプトを呼び出すには終了する必要があります (例: 切断して再接続する必要があります。すべてのステータスをリセットする必要があります)
5. ゲームオブジェクトを無効化/破壊する
ゲームオブジェクトコルーチンを無効化/破棄すると停止します。オブジェクトが再度アクティブ化されると、コルーチンは実行を継続しません。
gameObject.SetActive(false);
//通过销毁游戏对象方式和禁用同效果
//Destroy(gameobject)
それではない:
script.enabled = false;
つまり、非表示のスクリプトによってマウントされたゲーム オブジェクトです (親オブジェクトが非表示の場合も同様です)。
6. 利回りの概要:
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. 概要:
- StartCoroutine(function()); を使用して開始した場合、戻り値を受け取ることによってのみ停止できます [パラメータの数に制限はありません]
- StartCoroutine("関数名"); 形式で開始した場合は、StopCoroutine("関数名"); 形式で停止することもできます。 [欠点: パラメータは 1 つしか渡せません]
- どちらの開始フォームも StopAllCoroutines() によって制御されます。 StopAllCoroutines() は、現在のスクリプト内のすべてのコルーチンを停止できます。
- gameObject.SetActive(false); は、この GameObject 上のすべてのコルーチンを停止でき、コルーチンは再度アクティブ化されたときに続行されません。
- StopCoroutine(function()); script.enabled = false; コルーチンを停止できません。
5. 注意事項
コルーチンの使用はパフォーマンスに影響を与えるため、実際のプロジェクトでは注意して使用する必要があります。