(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]



エディタ拡張でUnityを再生していない時でもコルーチンを使い非同期処理が行える EditorCoroutineUtility【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加



この記事でのバージョン
Unity 2019.4.5f1


はじめに

UnityはMonoBehaviourのStartCoroutineを使うことで、

簡単にコルーチンを実行し、非同期処理を行う事が可能ですが、

private void Start () {
  //StartCoroutineを使ってコルーチンを実行
  StartCoroutine(DelayLog());
}

//0.5秒待ってからログを表示
private IEnumerator DelayLog(){
  Debug.Log("待ち開始……");
  yield return new WaitForSeconds(0.5f);
  Debug.Log("待ち終了!");
}
f:id:kan_kikuchi:20171214073408g:plain


この方法はエディタ拡張時(Unityを再生していない時)には使えないため、

エディタ拡張でコルーチンを利用したい場合はUniRxを使うなど一工夫必要でした。


しかし、いつの間にかエディタ拡張でコルーチンを使うためのEditorCoroutine

という物が実装されていたので、今回はこれを使ってみようという感じの記事。


イメージとしては以下のような感じです。

f:id:kan_kikuchi:20200828080630g:plain



導入

まずEditorCoroutineの導入にはPackageManagerを使います。

導入と言ってもWindow/Package Mangerを選び、

f:id:kan_kikuchi:20200828071003j:plain


Editor Coroutineを検索し、Installを押すだけで完了です。

f:id:kan_kikuchi:20200828071047j:plain



使い方

次に使い方ですが、こちらもMonoBehaviourのStartCoroutineの代わりに

EditorCoroutineUtilityのStartCoroutineを使うだけ。


実際にEditorCoroutineUtilityを使って

最初の例のような一定時間待機する処理(とそのウィンドウ)を作ってみると以下のような感じになります。

using System.Collections;
using UnityEngine;
using UnityEditor;
using Unity.EditorCoroutines.Editor;//EditorCoroutineUtilityを使うのに必要

/// <summary>
/// EditorCoroutineを試すためのウィンドウ
/// </summary>
public class EditorCoroutineSampleWindow : EditorWindow {
    
  //=================================================================================
  //初期化
  //=================================================================================
    
  //ウィンドウを開く
  [MenuItem("Window/EditorCoroutineSample")]
  private static void Open(){
    GetWindow<EditorCoroutineSampleWindow>();
  }
    
  //=================================================================================
  //更新
  //=================================================================================
    
  private void OnGUI() {
    //待機開始ボタン
    if (GUILayout.Button("待つ")) {
      //第2引数にobjectが必要(基本thisで大丈夫)
      EditorCoroutineUtility.StartCoroutine(DelayLog(), this);
    }
  }
    
  //0.5秒待ってからログを表示
  private IEnumerator DelayLog(){
    Debug.Log("待ち開始……");
    //WaitForSecondsではなくEditorWaitForSecondsなのに注意
    yield return new EditorWaitForSeconds(0.5f);
    Debug.Log("待ち終了!");
  }
    
}
f:id:kan_kikuchi:20200828080630g:plain


ちなみにStartCoroutineの返り値でEditorCoroutineが受け取れ、

それをStopCoroutineに渡して実行することで、コルーチンを止める事も可能です。

//実行したコルーチンを受け取る
EditorCoroutine coroutine = EditorCoroutineUtility.StartCoroutine(DelayLog(), this);

//コルーチンを止める
EditorCoroutineUtility.StopCoroutine(coroutine);


なおUnity 2020.1から追加されたProgressを使えば進捗を簡単かつ分かりやすく表示出来ます。

f:id:kan_kikuchi:20200902073739g:plain