Cooooding!!

Unity(C#)を使ったゲーム開発関連Tipsなど

リストの中から文字列で絞り込んで要素を選択するEditor用GUIを作る【Unity】

概要

リストの中から要素を選択させるGUIを作る場合、EditorGUILayout.Popupを使う方法がありますが要素が大量になってくると/で区切って分類しても探すのに苦労することがあります。そこで他にいい機能がないか探してみたところOdinの中にOdinSelectorというものを見つけたので試してみました。

f:id:nyama41:20190503161944p:plain

使用例

まずは選択ウィンドウの実装をします。

  1. OdinSelectorのGeneric引数に要素の型を指定して継承
  2. 必要ならコンストラクタでパラメーターを受け取る
  3. BuildSelectionTreeをoverrideして選択可能な要素をAddしていく

今回は指定された型が持つメソッドを選択するものを作ってみます。

using Sirenix.OdinInspector.Editor;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

/// <summary>
/// 指定されたTypeのメソッドを選択するOdinSelector
/// </summary>
public class MethodInfoSelector : OdinSelector<MethodInfo>
{
    private System.Type m_Type;

    public MethodInfoSelector(System.Type type)
    {
        m_Type = type;
    }

    protected override void BuildSelectionTree(OdinMenuTree tree)
    {
        tree.Selection.SupportsMultiSelect = false;
        // 選択可能な要素をリストアップ
        var flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
        foreach (var member in m_Type.GetMethods(flags))
        {
            var path = string.Format("{0}.{1}", m_Type.FullName, member.Name);
            tree.Add(path, member);
        }
    }
}

このSelectorを使うときは以下のように使います。

using Sirenix.OdinInspector.Editor;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    public string m_Value;

    [UnityEditor.CustomEditor(typeof(NewBehaviourScript))]
    private class Editor : UnityEditor.Editor
    {
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            // 選択ボタンを押したらウィンドウを開く
            if (GUILayout.Button("選択"))
            {
                var behaviour = target as NewBehaviourScript;
                // Vector3のメソッドを選択する
                var selector = new MethodInfoSelector(typeof(Vector3));
                selector.SelectionChanged += (e) =>
                {
                    var selections = e.ToArray();
                    if (selections.Length > 0)
                    {
                        // 選択されたメソッドの名前を格納する
                        behaviour.m_Value = selections[0].Name;
                    }
                };
                selector.ShowInPopup();
            }
        }
    }
}

このコンポーネントをGameObjectに付けて選択ボタンを押すと以下のようにウィンドウが表示されます。
f:id:nyama41:20190503161846p:plain

「Search」と書かれたところに文字列を入力すると絞り込むことができます。
f:id:nyama41:20190503161944p:plain

おまけ

  • System.Typeを選択したい場合はTypeSelectorというものが既にある
  • Selectorに現在の値をセットしたい場合はSetSelectionを呼ぶ

環境

  • Unity 2018.3.14f1
  • Odin Inspector 2.0.19
  • VisualStudio 2019