こんにちは、Unityエンジニアのオオバです。
結論から話すと、コルーチンは実行中のUnity上でのみ動きます。Editモード中(停止中のUnity)では基本的にコルーチンは動きません。しかしUnity公式が提供するパッケージ 「Editor Coroutines」 を使用することでEditモード中のUnityでも簡単にコルーチンを実行することができます。
そこで本記事では Editor Coroutinesパッケージ の使い方から注意点まで詳しく解説します。エディタを拡張してEditモード中に通信をしたくなる時があるのです。通信とは非同期処理。非同期処理といえばコルーチンが候補にあがります。Editモード中のコルーチンは意外と需要が発生するため、スキルとして手に入れておくことをおすすめします。ぜひ最後まで読んでみてください。
→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら
Editor Coroutinesのインストール
本記事はUnity2021.3.0f1を使用していますが、Editor Coroutinesはデフォルトでインストールされています。ゆえに、特にインストール作業は発生しません。
メニューWindow > Package Manager
からPackage Managerウィンドウを開いてみましょう。Editor Coroutinesを探して選択してみてください。

上図のように、Editor Coroutinesは削除しようにも「Remove」ボタンが押せない状態のため、間違ってアンインストールすることもないのです。つまり削除されることもないため安心してEditor Coroutinesを使っていきましょう。
Editor Coroutinesの使い方
ではEditor Coroutinesの具体的な使い方を解説します。例としてEditorWindow内でコルーチンを実行するサンプルを作ってみます。
【準備】コルーチンを動かすEditorウィンドウの作成
まずはTestWindowというEditorウィンドウを作ります。以下のソースコードを「TestWindow.cs」というC#スクリプトファイルを作成してコピペしてくみてください。
using System.Collections;
using UnityEditor;
using UnityEngine;
public class TestWindow : EditorWindow
{
[MenuItem("Test/TestWindow")]
private static void Init() => CreateWindow<TestWindow>().Show();
// カウントアップするコルーチン
private static IEnumerator CountUpCoroutine()
{
var count = 0;
while (true)
{
Debug.Log(count++.ToString());
yield return null;
}
}
}

するとUnityのメニューに「Test」が追加されます。
上図のように「TestWindow」をクリックしてEditorウィンドウを表示させておきましょう。

このように空のEditorウィンドウが作られます。
Editorウィンドウにボタンを追加
このEditorウィンドウにボタンを追加してコルーチンを動かすトリガーを追加します。
private void OnGUI()
{
if (GUILayout.Button("Start", GUILayout.Height(30f)))
{
}
if (GUILayout.Button("Stop", GUILayout.Height(30f)))
{
}
}
OnGUIメソッド内にEditorウィンドウ内の表示物を実装します。上記のコードをTestWindow.cs内に追加してください。

すると、上図のようにボタンが2つ追加されました。このボタン処理の中にコルーチンの実行と停止処理を記述していきます。
Editor Coroutinesでコルーチンを実行する方法
Editモード中は通常のコルーチン実行メソッド「StartCoroutine」は動きません。代わりに EditorCoroutineUtility.StartCoroutine
を使います。ではStartボタンをクリックしたらコルーチンが実行するようにコードを変更します。
if (GUILayout.Button("Start", GUILayout.Height(30f)))
{
EditorCoroutineUtility.StartCoroutine(CountUpCoroutine(), this);
}
「EditorCoroutineUtility.StartCoroutine」の第1引数にコルーチン、第2引数にコルーチンを紐付けるオブジェクトを指定します。今回は「this」つまりTestWindow自身です。では、コルーチンを実行してみましょう。

このようにConsoleウィンドウに、数値がカウントアップすることが確認できました。しかしこの状態ではコルーチンを止める事ができません。Editorウィンドウを閉じてもしばらく動き続けてしまいます。そこで次の章ではEditor Coroutinesのコルーチンの止め方を解説します。
Editor Coroutinesのコルーチンの止め方
Editor Coroutinesのコルーチンの止め方は通常のコルーチンと基本的に同じです。
①EditorCoroutineをStartCoroutineの戻り値として受け取る
②StopCoroutineの引数にEditorCoroutineを渡す
EditorCoroutineUtility.StartCoroutineメソッドの戻り値はEditorCoroutine型のインスタンスです。EditorCoroutineインスタンスをEditorCoroutineUtility.StopCoroutineの引数に渡すことでコルーチンは止まります。
次のコードを見ていきましょう。
// コルーチンを停止させるために保持する変数
private EditorCoroutine _coroutine;
private void OnGUI()
{
if (GUILayout.Button("Start", GUILayout.Height(30f)))
{
// コルーチンを開始
_coroutine = EditorCoroutineUtility.StartCoroutine(CountUpCoroutine(), this)
}
if (GUILayout.Button("Stop", GUILayout.Height(30f)))
{
// コルーチンを停止
EditorCoroutineUtility.StopCoroutine(_coroutine);
}
}
上記のコードを追加、編集することでStartボタン、Stopボタンにコルーチンの開始・停止を実装できます。
Editorウィンドウを閉じるときにもコルーチンを止める方法
Editorウィンドウを閉じたときにコルーチンを止めたい場合は、 OnDisable メソッド内に停止処理を書きましょう。
void OnDisable()
{
// Editorウィンドウを閉じたときにコルーチンを停止する
EditorCoroutineUtility.StopCoroutine(_coroutine);
}
上記のソースコードを追加することでEditorウィンドウを閉じたタイミングでコルーチンは停止します。ぜひ覚えておきましょう。
StopCoroutine以外のコルーチンの止め方
StopCoroutine以外にも止め方が存在します。それは、EditorCoroutineUtility.StartCoroutineの第2引数オブジェクトをメモリから削除することです。次のコードを見てみましょう。
if (GUILayout.Button("Start", GUILayout.Height(30f)))
{
EditorCoroutineUtility.StartCoroutine(CountUpCoroutine(), new object())
}
if (GUILayout.Button("Stop", GUILayout.Height(30f)))
{
GC.Collect();
}
StartCoroutineの第2引数を new object()
としました。この状態でガベージコレクションを実行します(GC.Collectを実行)。するとメモリからobjectが削除されるためコルーチンは止まります。
このテクニックが何かに使える気はしませんが、実装の仕組み自体を知っておくとどこかで役立つかもしれませんので、頭の片隅においておきましょう。
Editor CoroutinesはWaitForSecondsが使えない
Editor Coroutinesの注意点として、WaitForSecondsは使えません。WaitForSecondsとは指定した秒数処理を停止させるコルーチンの便利クラスです。
private static IEnumerator CountUpCoroutine()
{
var count = 0;
while (true)
{
Debug.Log(count++.ToString());
// 10秒待機する処理
yield return new WaitForSeconds(10f);
}
}
上記のように10秒待機する処理を書いてみます。

Editor Coroutinesを実行すると待機してくれません。
そこで 「WaitForSecondsRealtime」 を使うのです。すると指定した秒数待機して処理が実行されるようになります。次のソースコードは 「WaitForSecondsRealtime」 を使った例です。
private static IEnumerator CountUpCoroutine()
{
var count = 0;
while (true)
{
Debug.Log(count++.ToString());
yield return new WaitForSecondsRealtime(1f);
}
}

するとこのように指定秒数待機したコルーチンが実装できます。ぜひ覚えておきましょう。
まとめ
この記事ではEditモード中にコルーチンを使えるパッケージ「Editor Coroutines」について解説してきました。簡単に内容をまとめます。
①EditorCoroutineUtility.StartCoroutineでコルーチンを開始
②EditorCoroutineUtility.StopCoroutineでコルーチンを停止
③指定秒数待機するときはWaitForSecondsRealtimeを使う
こんな感じです。
Editor Coroutinesの使い方は基本的に通常のコルーチンと同じです。1度使ってみるとコルーチンに慣れている人であれば普通に使えるようになると思います。
もし、Editモード中に非同期処理をはさみたい方は、Editor Coroutinesをぜひ使ってみてください。とても簡単にコルーチンを記述することができます。
最後に今回使用したソースコード全文を共有します。
using System.Collections;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEngine;
public class TestWindow : EditorWindow
{
[MenuItem("Test/TestWindow")]
private static void Init() => CreateWindow<TestWindow>().Show();
private EditorCoroutine _coroutine;
private void OnDisable()
{
// EditorWindowを閉じたらコルーチンが止まるようにする
StopEditorCoroutine();
}
private void OnGUI()
{
if (GUILayout.Button("Start", GUILayout.Height(30f)))
{
StartEditorCoroutine();
}
if (GUILayout.Button("Stop", GUILayout.Height(30f)))
{
StopEditorCoroutine();
}
}
/// <summary>
/// 1秒ごとにカウントアップするコルーチン
/// </summary>
private static IEnumerator CountUpCoroutine()
{
var count = 0;
while (true)
{
Debug.Log(count++.ToString());
yield return new WaitForSecondsRealtime(1f);
}
}
/// <summary>
/// コルーチン開始
/// </summary>
private void StartEditorCoroutine()
{
// コルーチンの二重実行回避用の条件分岐
if (_coroutine == null)
_coroutine = EditorCoroutineUtility.StartCoroutine(CountUpCoroutine(), this);
}
/// <summary>
/// コルーチン停止
/// </summary>
private void StopEditorCoroutine()
{
if (_coroutine == null) return;
EditorCoroutineUtility.StopCoroutine(_coroutine);
_coroutine = null;
}
}
この記事があなたのゲーム開発に少しでもお役に立てたら嬉しいです。

この記事が気に入ったらフォローしよう
- Unity2021.3.0f1
- Editor Coroutines v1.0.0