この記事でのバージョン
Unity 2017.2.0f3
はじめに
Unityでは通常、コルーチン(Coroutine)を実行したい場合は以下のように、
MonoBehaviourのStartCoroutineを使って実行します。
private void Start () { //StartCoroutineを使ってコルーチンを実行 StartCoroutine(DelayLog()); } //0.5秒待ってからログを表示 private IEnumerator DelayLog(){ Debug.Log("待ち開始……"); yield return new WaitForSeconds(0.5f); Debug.Log("待ち終了!"); }
しかし、エディタ拡張でMonoBehaviourないけど、コルーチンを使いたい!という時もあります。
今回はそんな時に役立つ記事です!
IEnumerator. MoveNext
StartCoroutineを使わずにコルーチンを使いたい場合は、
IEnumerator型で変数を作成し、そのMoveNextを実行するだけ。
実際にやってみると以下のような感じ。
public class DelayLogWindow : EditorWindow { private static IEnumerator _iEnumerator = null; //================================================================================= //初期化 //================================================================================= //メニューからウィンドウを表示 [MenuItem("Window/Delay Log Window")] public static void Open (){ DelayLogWindow.GetWindow (typeof(DelayLogWindow)); EditorApplication.update += Update; } private void OnEnable (){ EditorApplication.update += Update; } //================================================================================= //表示するGUIの設定 //================================================================================= private void OnGUI(){ if(GUILayout.Button ("実行")) { //コルーチンを作成 _iEnumerator = DelayLog (); } } private static void Update(){ if(_iEnumerator != null){ //コルーチンを実行 _iEnumerator.MoveNext(); } } //0.5秒待ってからログを表示 private IEnumerator DelayLog(){ Debug.Log("待ち開始……"); //エディタが開始されてからの時間を取得 double timeSinceStartup = EditorApplication.timeSinceStartup; //0.5秒経過するまで待機 while (EditorApplication.timeSinceStartup - timeSinceStartup < 0.5f) { yield return 0; } Debug.Log("待ち終了!"); _iEnumerator = null; } }
最初の例よりちょっと複雑になったように見えるかもしれませんが、重要なのは以下の2箇所だけです。
//コルーチンを作成
_iEnumerator = DelayLog ();
//コルーチンを実行
_iEnumerator.MoveNext();
あとはWaitForSecondsが使えないので、
EditorApplication.timeSinceStartupで経過時間を確認していたり、
OnGUIは常に実行され続けるわけではないので、
EditorApplication.updateを使って更新処理を行っていたりしています。
エディタ拡張でコルーチンが使えれば、
以下の記事のようにUnityWebRequestの送信も簡単に行えるようになります。
_enumerator = SendWebRequest(request, FinishConvert);
if(_enumerator != null){ while (_enumerator.MoveNext()) {} }
//変換リクエスト送信 private IEnumerator SendWebRequest(UnityWebRequest request, Action<bool, string> callback) { //リクエスト送信 yield return request.SendWebRequest(); //リクエストが完了するまで待機 while(!request.isDone){ yield return 0; }
ただし、StartCoroutineを使わない場合は、
request.isDoneを見て送信が完了するまで待機する必要があります。