コルーチンの記述と実行
コルーチンメソッドを記述して実行し、徐々にフェードアウトするエフェクトなど、複数のフレームでエフェクトを適用する。
読み終わるまでの所要時間 12 分最終更新 3日前
コルーチンは、実行をサスペンドし、後で再開できるメソッドです。Unity アプリケーションでは、コルーチンがあるフレームで実行を開始してから別のフレームで再開できるため、タスクを複数のフレームにスプレッドできます。
通常の非コルーチンメソッドは、呼び出し元にコントロールを返す前に最後まで実行されます。つまり、Unity ランタイムでは、アクションは 1 つのフレーム更新内で完了します。徐々にフェードアウトするエフェクトなど、メソッドの作業を複数のフレームでエフェクトにしたい場合は、コルーチンを使用できます。コルーチンは、HTTP 転送の待機、アセットのロード、ファイル入出力の完了など、長時間の非同期操作の処理にも役立ちます。
コルーチンの記述
オブジェクトのアルファ (不透明度) 値が見えなくなるまで徐々に減らすタスクについて考えてみます。フェードエフェクトが表示されるためには、一連のフレームで不透明度を減少させる必要があります。 メソッドを作成しようとした場合、以下のような記述が考えられます。
Fadevoid Fade(){ Color c = renderer.material.color; for (float alpha = 1f; alpha >= 0; alpha -= 0.1f) { c.a = alpha; renderer.material.color = c; }}
このメソッドはコルーチンではないため、1 つのフレーム更新内でループのすべてのイテレーションを実行し、オブジェクトはフェードアウトする代わりに即座に消えます。考えられる解決策の 1 つは、フレーム単位でフェードを実行するコードを 機能に追加することです。ただし、コルーチンを使用した方が便利な場合があります。
forUpdateコルーチンは return type and a 、yield return statement included somewhere in the body. The ステートメントを持つメソッドで、実行は中断されます。上記の メソッドは、次のようにコルーチンとして書き直すことができます。
IEnumeratoryield returnFadeIEnumerator フェード(){ Color c = renderer.material.color; for (float alpha = 1f; alpha >= 0; alpha -= 0.1f) { c.a = alpha; renderer.material.color = c; yield return null; }}
メソッドの本バージョンは、ステートメントで実行を中断する前に、ループのイテレーションを 1 回実行します。次のフレームでループを再開して別のイテレーションを実行し、徐々にフェード エフェクトを表示します。 メソッドのループカウンタは、コルーチンの生存期間にわたって正しい値を維持し、変数やパラメーターはステートメント間で保存されます。
yield return nullforFadeyieldコルーチンの開始と停止
実行中のコルーチンを設定するには、StartCoroutine メソッドを使用します。
void Update(){ if (Input.GetKeyDown("f")) { StartCoroutine(Fade()); }}
コルーチンを停止するには、StopCoroutine と StopAllCoroutines を使用します。コルーチンは次の場合にも停止します。
- の値は、スクリプトがアタッチされているゲームオブジェクトの
GameObject.activeSelfになります。false - MonoBehaviour スクリプトは Destroy の呼び出しで破棄されます。
コルーチンの再開
中断されたコルーチンがいつ実行を再開するかは、 ステートメントで指定された yield 命令によって異なります。は次のフレームで再開します。Unity には、指定した時間後、指定した条件が満たされたとき、またはプレイヤーループの特定の時点で再開するために使用できる、一連のカスタム yield 命令があります。詳細については、歩留まり手順リファレンスを参照してください。
yield returnyield return nullフェード エフェクトの例の場合、フェード エフェクトをフレームレートよりも低く安定したレートで発生させたい場合があります。次のように 命令をして、 メソッドの反復間に固定時間遅延を導入できます。
WaitForSecondsyield returnFadeIEnumerator フェード(){ Color c = renderer.material.color; for (float alpha = 1f; alpha >= 0; alpha -= 0.1f) { c.a = alpha; renderer.material.color = c; // Wait for 0.1 seconds before the next iteration yield return new WaitForSeconds(.1f); }}
コルーチン内から Unity をすることもできます。これは、コルーチンを と を使用する非同期コードと統合する場合に便利です。例えば、前の例では、 の代わりに を使用して同じエフェクトを実現できます。
Awaitableyield returnasyncawaityield return new WaitForSeconds(.1f)yield return Awaitable.WaitForSecondsAsync(.1f)編集モードのコルーチン
コルーチンは主にランタイムの特徴です。関連するランタイム yield 命令は 名前空間にあり、エディタの再生モードまたはスタンドアロンプラットフォームプレイヤーで実行されます。また、スクリプトで属性または属性を使用している場合は、編集モードで実行することもできますが、編集モードの更新ループはプレイヤーループほど固定的ではなく、規則的ではありません。
UnityEngine[ExecuteInEditMode][ExecuteAlways]編集モードで実行するように特別に設計されたコルーチンには、 Editor Coroutines パッケージを使用します。
テストのコルーチン
Unity Test Framework 再生モードテストで 属性がマークされている場合は、コルーチンとして実行され、テストから Unity エディターのカスタム命令を生成できます。詳細は、エディタの収率に関する説明 を参照してください。
[UnityTest]コルーチンパフォーマンス
コルーチンは、誤用されると隠れた割り当てやガベージコレクターのスパイクを引き起こす可能性があります。各コルーチンはステートマシンを作成します。これらを頻繁に(例えばフレームごとに)開始すると、オーバーヘッドが割り当てられ、追加されます。 は割り当てを行わず、 のような yield 命令を行います。頻繁に再利用されるものをキャッシュし、デリゲートとキャプチャの割り当てを防ぐために、とでラムダを避けます。
IEnumeratoryield return nullnew WaitForSecondsWaitUntilWaitWhile新しいコルーチンを繰り返し開始するのではなく、でループする長期コルーチンを優先します。固定された期間を持つキャッシュまたはプール 。コルーチンは、その所有者とキャプチャされた変数への参照を保持します。漏洩を避けるために、で終了または停止していることを確認します。
yield return nullWaitForSecondsMonoBehaviour.StopCoroutine特に制約されたプラットフォームでは、常にプロファイルを行い、割り当てを確認および特定してください。詳細は、コルーチンの分析 を参照してください。