【Unity】【エディタ拡張】デバッグ用のドロップダウンメニューを作成する

こんな感じでクリックするとデバッグ用のメニューが開くドロップダウンを作ってみます。

f:id:halya_11:20190202172641g:plain

レイアウトは自由に組めるので別にデバッグ用じゃなくてもいいのですが、今回はデバッグ用を想定して作っています。
デバッグメニューは目立つところに置くと邪魔になるのでこういうのを汎用的に作っておくと便利です。

Unity2018.3.1

ソースコード

まず、デバッグウィンドウをPopupWindowで作ります。
PopupWindowについては下の記事で説明しています。

light11.hatenadiary.com

それではソースコードです。

using UnityEngine;
using UnityEditor;

public class ExampleDebugWindow : PopupWindowContent
{
    /// <summary>
    /// デバッグメニューの種類
    /// </summary>
    private enum MenuType
    {
        Play,
        Pause,
        Resume,
        Stop,
    }

    private float WindowWidth { get; } = 200;
    private float WindowHeight { 
        get {
            var height = 0.0f;
            var singleLineHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
            // タイトル部分
            height += singleLineHeight;
            // ボタン部分
            height += System.Enum.GetValues(typeof(MenuType)).Length * singleLineHeight;
            // 最下部の余白
            height += EditorGUIUtility.standardVerticalSpacing;

            return height;
        }
    }

    /// <summary>
    /// サイズを取得する
    /// </summary>
    public override Vector2 GetWindowSize() => new Vector2(WindowWidth, WindowHeight);

    /// <summary>
    /// GUI描画
    /// </summary>
    public override void OnGUI(Rect rect)
    {
        var fieldRect = rect;
        fieldRect.height = EditorGUIUtility.singleLineHeight;

        // タイトルを描画
        GUI.Label(fieldRect, "Debug Menu", EditorStyles.boldLabel);
        fieldRect.y += EditorGUIUtility.singleLineHeight;
        fieldRect.y += EditorGUIUtility.standardVerticalSpacing;
        
        // ボタンを描画
        fieldRect.xMin += 8;
        fieldRect.xMax -= 8;
        foreach (MenuType type in System.Enum.GetValues(typeof(MenuType))) {
            GUI.Button(fieldRect, type.ToString());
            fieldRect.y += EditorGUIUtility.singleLineHeight;
            fieldRect.y += EditorGUIUtility.standardVerticalSpacing;
        }
    }

    /// <summary>
    /// 開いたときの処理
    /// </summary>
    public override void OnOpen()
    {
    }

    /// <summary>
    /// 閉じたときの処理
    /// </summary>
    public override void OnClose()
    {
    }
}

外側からEnumとか渡して初期化したほうが汎用的になるかと思います。
これをCustomEditorとかから開きます。

[CustomEditor(typeof(ExampleBehaviour))]
public class SerializedObjectTestEditor : Editor
{
    public override void OnInspectorGUI()
    {
        // PopupWindowを表示する位置
        // if文の中でGUILayoutUtility.GetLastRect()でなぜかうまく取得できなかったのでここで取得している
        var debugWindowRect = GUILayoutUtility.GetRect(0,0);
        debugWindowRect.y +=  EditorGUIUtility.singleLineHeight;

        // ボタン
        // ツールバーで使うときには第3引数にEditorStyles.toolbarDropDownを
        if (EditorGUILayout.DropdownButton(new GUIContent("Debug"), FocusType.Passive)) {
            
            PopupWindow.Show(debugWindowRect, new ExampleDebugWindow());
        }
    }
}

PropertyDrawerなど、EditorGUIで組む場合はEditorGUI.DropdownButtonを使います。

// ボタン
// ツールバーで使うときには第3引数にEditorStyles.toolbarDropDownを
if (EditorGUI.DropdownButton(position, new GUIContent("Debug"), FocusType.Passive)) {
    PopupWindow.Show(position, new ExampleDebugWindow());
}

結果

こんな感じのメニューが出来上がります。

f:id:halya_11:20190202172641g:plain

Windowの中身は自由に組めるので、デバッグメニュー以外にも様々な用途に使用できます。

参考にしたもの

今回のビューを作るにあたって、Sceneビューのツールバーが良い感じだなと思って作り始めました

f:id:halya_11:20190202172747p:plain

そのため、そのあたりのC# Referenceを参考にして作っています。

github.com

github.com

関連

light11.hatenadiary.com