• トップ
  • ブログ一覧
  • EditorWindowでunityを便利にしてみた
  • EditorWindowでunityを便利にしてみた

    広告メディア事業部広告メディア事業部
    2020.02.25

    IT技術

    EditorWindow で unity を便利に

    EditorWindow(エディターウィンドウ) とは、Unity(ユニティ)を、もっと便利にするための機能の1つです。

    Unity開発において、「非エンジニアが、システムを操作する際に、触りやすいようにしたい」という事が業務で出てくると思います。

    例えばですが

    「Assets 配下の .animファイルから、StatemachineBehaviour がアタッチされている、State を含むファイルを探すシステムを作ってほしい」

    「翻訳ファイルの中から、未翻訳の項目を見つけたい」

    といった要望や、それに近い問題に直面したした際、インターフェースに EditorWindow を活用できる可能性があります。

    そこで、今回は「EditorWindow」の、便利な使い方をまとめてみたいと思います!

    EditorWindow はどんな時に必要?

    早速ですが、EditorWindow を使うと、Unity 上に、こんなウィンドウを作ることができます。

    製作物に直接関わる機能ではないですが、主に大規模な開発の時に役立ちます。

    どんな場面で役立つのか?

    先ほどの依頼を例に挙げると…

    「翻訳ファイルの中から未翻訳の項目を見つけたい」

    こちら、翻訳自体はエンジニアではない方が担当することが多いはずです。

    そんな時に、便利機能を EditorWindow で提供すれば、Unity に詳しくない方でも、翻訳漏れを簡単に検索出来るようになります。

    その結果、効率化につながるのです。

    EditorWindow の作り方

    それでは、EditWindow の作り方を、順を追って解説したいと思います。

    1. スクリプトファイルを作成

    まず、EditWindow を作るには、「Editor」という名前のフォルダを作成しなくてはなりません

    作成する場所については、Assets 以下ならどこでも構いませんが、今回は、Assets フォルダ直下に作成したいと思います。

    作成後は、Editor フォルダの下に、スクリプトを新規作成します。

    なぜ、Editorフォルダ?
    Editorという名前のフォルダは、ビルド時に無視されるからです。
    今回のスクリプトはプロジェクトに必要なコードではなく、あくまでUnity上での作業効率を向上させるためのものであるため、ビルドに含む必要がありません。
    また、このスクリプトをビルドに含めようとするとエラーになります。

    2. EditorWindow を継承させる

    新規作成したスクリプトの、MonoBehaviour の部分を、EditorWindow に書き換えます。

    デフォルトでは、「Start関数」と「Update関数」が記述されていますが、両方消しておきましょう!

    1using UnityEngine;
    2using UnityEditor;
    3
    4public class WindowTest : EditorWindow
    5{
    6
    7}

    3. OnGUI関数を定義する

    次に、GUI を描画するための関数である、「OnGUI関数」を定義します。

    この関数内に、描画のための処理を記述することになります。

    今回は、お約束でウインドウズ上に「Hello World!」というテキストを表示させてみましょう!

    1using UnityEngine;
    2using UnityEditor;
    3
    4public class WindowTest : EditorWindow
    5{
    6    void OnGUI()
    7    {
    8        GUILayout.Label("Hello World!", EditorStyles.boldLabel);
    9
    10    }
    11}

    4. メニューバーに追加する

    次に、Unity 上部のメニューバーから、先ほど作った EditorWindow を開けるようにしてみます。

    それには、以下のスクリプトを追加するだけで簡単に実装できます。

    1   [MenuItem("Test/WindowTest")]
    2    static void Init()
    3    {
    4        WindowTest window = (WindowTest)EditorWindow.GetWindow(typeof(WindowTest));
    5        window.Show();
    6    }

    なお MenuItem() のかっこの中の文字列は、メニューバー上での表示名になります。

    仮に、”Test/WindowTest” と入力した場合、下の画像のように表示されるはずです。

    5. EditorWindow の完成

    以上で完成です。

    スクリプト全体は、以下のようになりました。

    1using UnityEngine;
    2using UnityEditor;
    3
    4public class WindowTest : EditorWindow
    5{
    6   
    7    [MenuItem("Test/WindowTest")]
    8    static void Init()
    9    {
    10        WindowTest window = (WindowTest)EditorWindow.GetWindow(typeof(WindowTest));
    11        window.Show();
    12    }
    13
    14    void OnGUI()
    15    {
    16        GUILayout.Label("Hello World!", EditorStyles.boldLabel);
    17
    18    }
    19}

    これで、メニューバーに「Test」という項目が追加されていると思います。

    Test > WindowTestとクリックすると、以下画像のように、先ほど作ったEditorWindowを開くことが出来るはずです。

    6. 小ネタ

    EditorWindow について、「3つ」ほど小ネタを紹介したいと思います。

    1:MonoBehaviour 継承時と違い、クラス名とファイル名は別でも問題ありません。

    2:表示名を ”Test/WindowTest” としていますが、スラッシュ区切りを増やすと、さらに階層を深くすることが可能です。

    3:実は、スクリプトを作成するフォルダ階層は、Editor の下じゃなくても大丈夫です。
    スクリプト全体を#if UNITY_EDITOR で囲うことで、Editor フォルダ配下にスクリプトを置くのと、同じ効果が得ることができます。

    EditorWindow の使い方

    OnGUI 内での処理の書き方の例に、「メモ帳代わりに使えるウィンドウ」を作ってみましょう。

    上記の作り方の説明では、テキストの表示のみを行いました。

    今回は、「文字入力を受け付けたり」「ボタンを表示」させる実装を追加したいと思います。

    作成したウィンドウ

    スクリプト全体

    「文字入力機能」と「ボタン表示」を追加したスクリプト全体は、以下となります。

    1using UnityEngine;
    2using UnityEditor;
    3
    4public class WindowTest : EditorWindow
    5{
    6   
    7    [MenuItem("Test/Memo")]
    8    static void Init()
    9    {
    10        WindowTest window = (WindowTest)EditorWindow.GetWindow(typeof(WindowTest));
    11        window.Show();
    12    }
    13
    14    Vector2 pos = Vector2.zero;
    15    private string log = "";
    16    private string current = "";
    17    void OnGUI()
    18    {
    19       
    20        GUILayout.Label("memo", EditorStyles.boldLabel);
    21        //スクロールできる領域を作る。
    22        pos = GUILayout.BeginScrollView(pos);
    23        GUILayout.Label(log);
    24        GUILayout.EndScrollView();
    25       
    26        //日本語入力に変更できるようにする
    27        Input.imeCompositionMode = IMECompositionMode.On;
    28
    29
    30        //文字入力できる領域を作る(改行可能)
    31        current = GUILayout.TextArea(current,GUILayout.Height(200));
    32        //ボタンを出す
    33        if (GUILayout.Button("ログに残す"))
    34        {
    35            log += current + "\n";
    36        }
    37
    38        if (GUILayout.Button("ログを消去"))
    39        {
    40            log = "";
    41        }
    42    }
    43}

    スクリプト内の説明

    また、スクリプト中にコメントを入れていますが、追加で覚えておいてもらいたいことを簡単に説明しておきたいと思います。

    【GUILayout.Button】
    ボタンを表示。押されるとtrueが返る。

    【GUILayout.TextArea】
    文字入力エリア表示。TextFieldもあるが、そちらは1行入力。

    【GUILayout.BeginScrollView】
    スクロールできる領域を作る。BeginとEndで囲まれた領域がスクロールできる領域となる。
    引数に現在の位置を取り、新しいスクロール位置が返るので、ローカル変数で保存しておく必要がある。

    スクリプトファイルカウンターを作ってみる

    さて、今まで作ってきたことを応用として、「現在Assets内に含まれる、csファイルの数をカウントする機能」を作ってみたいと思います。

    こちらは、「EditorWindow 上で、Assets 配下のファイルに対して、何かを行う機能を求められた場合」に活用できるかと思うので、早速作ってみたいと思います。

    スクリプト全体

    1using System.IO;
    2using UnityEngine;
    3using UnityEditor;
    4
    5public class WindowTest : EditorWindow
    6{
    7
    8   [MenuItem("Test/Count")]
    9   static void Init()
    10   {
    11       WindowTest window = (WindowTest) EditorWindow.GetWindow(typeof(WindowTest));
    12       window.Show();
    13   }
    14
    15   private int result = 0;
    16
    17
    18   int SearchCsFileRecursive(string path)
    19   {
    20       var count = 0;
    21       var files = Directory.GetFiles(path);
    22     
    23       foreach (var file in files)
    24       {
    25           var ext = Path.GetExtension(file);
    26           if (ext.ToLower() == ".cs")
    27           {//拡張子が.csなら
    28               count++;
    29           }
    30       }
    31       var directories = Directory.GetDirectories(path);
    32       foreach (var directory in directories)
    33       {//再帰的に検索
    34           Debug.Log(directory);
    35           count += SearchCsFileRecursive(directory);
    36       }
    37
    38
    39       return count;
    40      
    41   }
    42   void OnGUI()
    43   {
    44       GUILayout.Label("ファイル数 : " + result);
    45       if (GUILayout.Button("csファイル数カウント"))
    46       {
    47           result = SearchCsFileRecursive("Assets");
    48       }
    49   }
    50}

    SearchCsFileRecursive  が再帰関数になっており、渡されたフォルダパス以下の、全フォルダを検索できます。

    具体的な処理

    具体的な処理は下記の通りです。

    1. 直下のファイルリストを取得して、拡張子がcsのファイルをカウント
    2. 直下のフォルダリストを取得して、フォルダが存在すれば、それぞれのフォルダに1.~3.を実行し、返ってきたカウントを加算(存在しなければ3.へ)
    3. カウントの値を返す。

    実行

    実行すると、以下のように表示されるはずです。

    さいごに

    今回は、EditorWindow のやり方をまとめてみました!

    この機能を使えるようになれば、様々な Unity プロジェクトで開発の効率化を行うことが出来ると思います。

    今関わっている、Unityのプロジェクトで起きている問題に利用できないか、考えてみてはいかがでしょうか?

    解決する糸口になるかもしれません!

    是非、ご活用していただければ幸いです!

    こちらの記事もオススメ!

    featureImg2020.07.28Unity 特集知識編おすすめのゲームエンジン5選実装編※最新記事順に並べています。VR環境でテキストを表示する方法非同期式の入れ子処...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    広告メディア事業部

    広告メディア事業部

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background