第1章 エディター拡張で使用するフォルダー - エディター拡張入門

第1章 エディター拡張で使用するフォルダー

エディター拡張を始める最初の段階として、知っておかなければならないことがあります。この章では、エディター拡張の世界へ入る第一歩としてエディター拡張で重要な「フォルダー」について説明します。

1.1 Editor フォルダー

Editor フォルダーはエディターAPI を使用するための特別なフォルダーです。通常エディターAPI は、ランタイム *1 で動作はできません。

試しに次のコードを Assets フォルダー直下に作成し、Build Settings ウィンドウからビルドをしてみましょう。

using UnityEngine;
using UnityEditor;

public class NewBehaviourScript : MonoBehaviour
{
}

そうするとビルドが失敗し、次の画像のようにログが表示されます。

ビルドエラー。名前空間「UnityEditor」が見つからない

図1.1: ビルドエラー。名前空間「UnityEditor」が見つからない

これはビルド時に生成される Assembly-CSharp.dll が、UnityEditor.dll の参照を行わないためです。

ですが、開発時の Unity エディターで生成される Assembly-CSharp.dll には UnityEditor.dll の参照が行われているためスクリプトのコンパイルエラーは発生しません。ビルド時に生成される Assembly-CSharp.dll では UnityEditor.dll の参照が行われないということを覚えておきましょう。この仕様を知らないと「突然ビルドが通らなくなった」原因になってしまいます。

Monodevelop で見ると UnityEditor.dll の参照を行っている。

図1.2: Monodevelop で見ると UnityEditor.dll の参照を行っている。

さて、このままではエディターAPI を満足に使用できません。ビルドごとにエディターAPI を使用しているスクリプトファイルを除去するということも考えられますがそれは手間です。

UnityEditor では Assembly-CSharp-Editor.dll を生成し、エディターAPI とランタイム API の住み分けを行うことでこの問題を解決しています。この Assembly-CSharp-Editor.dll はビルド時には含まれないのでビルドエラーも発生しません。Assembly-CSharp-Editor.dllEditor フォルダー内のスクリプトファイルがコンパイルされて生成されます。

Editor フォルダーの場所は特に制限はありません。どこにでも複数作成できます。

  • Assets/Editor
  • Assets/MyFolder/Scripts/Editor
  • Assets/Standard Assets/Editor
フォルダー名が Editor であれば場所は特に指定はない

図1.3: フォルダー名が Editor であれば場所は特に指定はない

ただし、「Standard Assets」「Pro Standard Assets」「Plugins」フォルダー内に Editor フォルダーを作成した場合は、スクリプトは Assembly-CSharp-Editor-firstpass.dll へとコンパイルされます。

firstpass が参照されているのが分かる

図1.4: firstpass が参照されているのが分かる

Assembly-CSharp-Editor からは firstpass を参照できますが、逆に、firstpass からは Assembly-CSharp-Editor.dll を参照できないので気をつけてください。

Editor フォルダーに含めずに動作させる方法

ランタイムで動作するスクリプトと一緒にエディターAPI を記述することはよくあります。その場合は#define を利用します。UnityEditor上のみで UNITY_EDITOR シンボルが定義されています。これにより、ビルド時のスクリプトコンパイルでは UNITY_EDITOR が定義されていないので#if UNITY_EDITOR で囲ったコードは除去されます。

using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

public class NewBehaviourScript : MonoBehaviour
{
    void OnEnable ()
    {
        #if UNITY_EDITOR
        EditorWindow.GetWindow<ExampleWindow> ();
        #endif
    }
}

1.2 Editor Default Resources フォルダー

「Resources」フォルダーのようにエディター拡張のみで使用するリソースを格納しておくフォルダーです。「Editor Default Resources」フォルダー内にあるアセットは EditorGUIUtility.Load でアクセスすることが可能です。

logo.png の画像ファイルがある

図1.5: logo.png の画像ファイルがある

var tex = EditorGUIUtility.Load ("logo.png") as Texture;

ビルトインのリソース

もともと、Editor Default Resources フォルダーは、ビルトインのリソースを扱うためのフォルダーであり、ユーザーが「このフォルダーにリソースを置く」目的で使うものではありません。

このフォルダーの目的は「ビルトインのリソースを置き換える」目的で使います。

ビルトインのリソースをロードする

エディターで使用するビルトインのリソースは、1つのアセットバンドルにまとめられています。確認のために、EditorGUIUtility.GetEditorAssetBundle でアセットバンドルを取得します。

AssetBundle.GetAllAssetNames でパスを確認

図1.6: AssetBundle.GetAllAssetNames でパスを確認

[InitializeOnLoadMethod]
static void GetBultinAssetNames ()
{
    var flags = BindingFlags.Static | BindingFlags.NonPublic;
    var info = typeof(EditorGUIUtility).GetMethod ("GetEditorAssetBundle", flags);
    var bundle = info.Invoke (null, new object[0]) as AssetBundle;

    foreach (var n in bundle.GetAllAssetNames()) {
        Debug.Log (n);
    }
}

パスを確認したら後は EditorGUIUtility.Load でアセットをロードします。必ず、Load 関数でアセットをロードしてください。先ほど取得したアセットバンドルからロードしたものを使ってはいけません。

EditorGUIUtility.Load は、まず Unity プロジェクトの「"Assets/Editor Default Resources/" + path」にアセットがあるか探します。その時にアセットがあれば、そのアセットを使用し、なければビルトインのアセットバンドルからアセットをロードします。この仕様により、「ビルトインのリソースを置き換える」ことが可能です。

[*1] ビルドして実機上で動かすことを指します

著者紹介 第2章 標準で使えるエディター拡張機能