ドキュメント

Unity Engine

Unity Engine

コルーチンの記述と実行

コルーチンメソッドを記述して実行し、徐々にフェードアウトするエフェクトなど、複数のフレームでエフェクトを適用する。
読み終わるまでの所要時間 12 分最終更新 3日前

コルーチンは、実行をサスペンドし、後で再開できるメソッドです。Unity アプリケーションでは、コルーチンがあるフレームで実行を開始してから別のフレームで再開できるため、タスクを複数のフレームにスプレッドできます。
通常の非コルーチンメソッドは、呼び出し元にコントロールを返す前に最後まで実行されます。つまり、Unity ランタイムでは、アクションは 1 つのフレーム更新内で完了します。徐々にフェードアウトするエフェクトなど、メソッドの作業を複数のフレームでエフェクトにしたい場合は、コルーチンを使用できます。コルーチンは、HTTP 転送の待機、アセットのロード、ファイル入出力の完了など、長時間の非同期操作の処理にも役立ちます。
重要
コルーチンとスレッドを混同しないでください。コルーチン内で実行される同期操作は、引き続きメインスレッドで実行されます。メインスレッドに費やされる CPU 時間を削減したい場合は、ほかのスクリプトコードと同様に、コルーチンで操作をブロックしないようにすることが重要です。Unity でマルチスレッドコードを使用する場合のオプションは次のとおりです。

コルーチンの記述

オブジェクトのアルファ (不透明度) 値が見えなくなるまで徐々に減らすタスクについて考えてみます。フェードエフェクトが表示されるためには、一連のフレームで不透明度を減少させる必要があります。
Fade
メソッドを作成しようとした場合、以下のような記述が考えられます。
void Fade(){ Color c = renderer.material.color; for (float alpha = 1f; alpha >= 0; alpha -= 0.1f) { c.a = alpha; renderer.material.color = c; }}
このメソッドはコルーチンではないため、1 つのフレーム更新内で
for
ループのすべてのイテレーションを実行し、オブジェクトはフェードアウトする代わりに即座に消えます。考えられる解決策の 1 つは、フレーム単位でフェードを実行するコードを
Update
機能に追加することです。ただし、コルーチンを使用した方が便利な場合があります。
コルーチンは
IEnumerator
return type and a 、yield return statement included somewhere in the body. The
yield return
ステートメントを持つメソッドで、実行は中断されます。上記の
Fade
メソッドは、次のようにコルーチンとして書き直すことができます。
IEnumerator フェード(){ Color c = renderer.material.color; for (float alpha = 1f; alpha >= 0; alpha -= 0.1f) { c.a = alpha; renderer.material.color = c; yield return null; }}
メソッドの本バージョンは、
yield return null
ステートメントで実行を中断する前に、
for
ループのイテレーションを 1 回実行します。次のフレームでループを再開して別のイテレーションを実行し、徐々にフェード エフェクトを表示します。
Fade
メソッドのループカウンタは、コルーチンの生存期間にわたって正しい値を維持し、変数やパラメーターは
yield
ステートメント間で保存されます。

コルーチンの開始と停止

実行中のコルーチンを設定するには、StartCoroutine メソッドを使用します。
void Update(){ if (Input.GetKeyDown("f")) { StartCoroutine(Fade()); }}
コルーチンを停止するには、StopCoroutine と StopAllCoroutines を使用します。コルーチンは次の場合にも停止します。
  • GameObject.activeSelf
    の値は、スクリプトがアタッチされているゲームオブジェクトの
    false
    になります。
  • MonoBehaviour スクリプトは Destroy の呼び出しで破棄されます。
注
MonoBehaviourスクリプトを有効にして
false
を無効にしても、コルーチンは停止しません。

コルーチンの再開

中断されたコルーチンがいつ実行を再開するかは、
yield return
ステートメントで指定された yield 命令によって異なります。
yield return null
は次のフレームで再開します。Unity には、指定した時間後、指定した条件が満たされたとき、またはプレイヤーループの特定の時点で再開するために使用できる、一連のカスタム yield 命令があります。詳細については、歩留まり手順リファレンスを参照してください。
フェード エフェクトの例の場合、フェード エフェクトをフレームレートよりも低く安定したレートで発生させたい場合があります。次のように
WaitForSeconds
命令を
yield return
して、
Fade
メソッドの反復間に固定時間遅延を導入できます。
IEnumerator フェード(){ 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
Awaitable
を
yield return
することもできます。これは、コルーチンを
async
と
await
を使用する非同期コードと統合する場合に便利です。例えば、前の例では、
yield return new WaitForSeconds(.1f)
の代わりに
yield return Awaitable.WaitForSecondsAsync(.1f)
を使用して同じエフェクトを実現できます。
重要
ジェネリック
Awaitable<T0>
をコルーチンから
yield return
することはできません。

編集モードのコルーチン

コルーチンは主にランタイムの特徴です。関連するランタイム yield 命令は
UnityEngine
名前空間にあり、エディタの再生モードまたはスタンドアロンプラットフォームプレイヤーで実行されます。また、スクリプトで
[ExecuteInEditMode]
属性または
[ExecuteAlways]
属性を使用している場合は、編集モードで実行することもできますが、編集モードの更新ループはプレイヤーループほど固定的ではなく、規則的ではありません。
編集モードで実行するように特別に設計されたコルーチンには、 Editor Coroutines パッケージを使用します。

テストのコルーチン

Unity Test Framework 再生モードテストで
[UnityTest]
属性がマークされている場合は、コルーチンとして実行され、テストから Unity エディターのカスタム命令を生成できます。詳細は、エディタの収率に関する説明 を参照してください。

コルーチンパフォーマンス

コルーチンは、誤用されると隠れた割り当てやガベージコレクターのスパイクを引き起こす可能性があります。各コルーチンは
IEnumerator
ステートマシンを作成します。これらを頻繁に(例えばフレームごとに)開始すると、オーバーヘッドが割り当てられ、追加されます。
yield return null
は割り当てを行わず、
new WaitForSeconds
のような yield 命令を行います。頻繁に再利用されるものをキャッシュし、デリゲートとキャプチャの割り当てを防ぐために、
WaitUntil
と
WaitWhile
でラムダを避けます。
新しいコルーチンを繰り返し開始するのではなく、
yield return null
でループする長期コルーチンを優先します。固定された期間を持つキャッシュまたはプール
WaitForSeconds
。コルーチンは、その所有者とキャプチャされた変数への参照を保持します。漏洩を避けるために、
MonoBehaviour.StopCoroutine
で終了または停止していることを確認します。
特に制約されたプラットフォームでは、常にプロファイルを行い、割り当てを確認および特定してください。詳細は、コルーチンの分析 を参照してください。

追加リソース