Unity Editor の拡張機能には,ドロップダウンメニューの作成方法が複数用意されています。
その中には,メニューにアイコンを設定できる物があります。
本稿では,その使い方について御説明いたします。
(複数選択式プルダウンメニュー MaskField には,アイコンを設定する事は出来ません。)
(Unity 2018.3.0f2)
EditorGUILayout.Popup
配列string[]
の要素を項目として,プルダウンメニューを作成する関数です。
まずは,完成したメニューをお見せします。
コードは,下記のようになっております。
using UnityEngine; // LINQ の使用 using System.Linq; // ここからエディター上でのみ有効 #if UNITY_EDITOR using UnityEditor; // エディター拡張クラス [CustomEditor(typeof(Extend))] public class ExtendedEditor : Editor {// Editor クラスを継承 // Extend クラスの変数を扱うために宣言 Extend extend; void OnEnable() {// 最初に実行 // Extend クラスに target を代入 extend = (Extend)target; } // 仕切り static readonly string Divider = string.Empty; // 未選択状態 static readonly string Unselected = "(Unselected)"; public override void OnInspectorGUI() {// Inspector に表示 // これ以降の要素に関してエディタによる変更を記録 EditorGUI.BeginChangeCheck(); // SerializedObject の内容を更新 serializedObject.Update(); // Inspector のコンポーネントに表示する項目名 var text = "List"; // ツールチップのテキスト var tooltip = "Popup list \"Items\" will be made out of this."; // ツールチップ入りラベルの作成 var label = new GUIContent(text, tooltip); // 配列の中身も表示する var includeChildren = true; // リストを取得 var property = serializedObject.FindProperty(nameof(extend.list)); // 配列フィールドの作成 EditorGUILayout.PropertyField(property, label, includeChildren); // SerializedObject の変更を適用 serializedObject.ApplyModifiedProperties(); // GUIContent から text を抽出してインデックス番号を付与した配列 var textList = extend.list .Select((GUIContent content) => content.text) .Select((string name, int number) => $"{number}: \r{name}") .ToArray(); // ドロップダウンの項目を作成 var list = new GUIContent[extend.list.Length].ToList(); for (var i = 0; i < extend.list.Length; i++) { // GUIContent の代入 list[i] = new GUIContent(textList[i], extend.list[i].image, extend.list[i].tooltip); } // リストに仕切りを追加 list.Add(new GUIContent(Divider)); // 未選択状態を追加 list.Add(new GUIContent(Unselected)); // Inspector のコンポーネントに表示する項目名 text = "Items"; // ツールチップのテキスト tooltip = "Select one item."; // ツールチップ入りラベルの作成 label = new GUIContent(text, tooltip); // 初期値として表示する項目のインデックス番号 var selectedIndex = (extend.list.Length == 0) ? -1 : (extend.index < 0) ? (extend.list.Length + 1) : extend.index; // プルダウンメニューに登録する文字列配列 var displayOptions = list.ToArray(); // プルダウンメニューの作成 var index = (extend.list.Length > 0) ? EditorGUILayout.Popup(label, selectedIndex, displayOptions) : selectedIndex; if (EditorGUI.EndChangeCheck()) {// 操作を Undo に登録 // Extend クラスの変更を記録 var objectToUndo = extend; // Undo メニューに表示する項目名 var name = "Extend"; // 記録準備 Undo.RecordObject(objectToUndo, name); // インデックス番号を登録 extend.index = index; } // 未選択状態のインデックス番号を -1 とする extend.index = (index > extend.list.Length) ? -1 : index; if ((extend.index != selectedIndex) && (extend.index >= 0)) {// 選択した項目のインデックス番号と項目名をログに出力 Debug.Log(extend.index); Debug.Log(extend.list[extend.index].text); } } } // ここまでエディター上でのみ有効 #endif // 同一オブジェクトへの複数追加を禁止 [DisallowMultipleComponent] public class Extend : MonoBehaviour {// エディター拡張の中身 // リスト public GUIContent[] list = { }; // 初期値は“未選択” public int index = -1; }
インデックス番号や未選択状態等は,個人的な好みとして追加しております。
文字列配列string[]
にインデックス番号を付与する方法として,今回はLINQのSelect
関数を使用しました。
SerializedObject の代入に関しては,nameof
演算子を使用しています。
C# のバージョンが 5 以下であれば,次のように記述してください。
// リストを取得 var property = serializedObject.FindProperty("list");
インデックス番号を付与するデリゲートには,文字列補間機能を使用しています。
C# のバージョンが 5 以下であれば,次のように記述してください。
// GUIContent から text を抽出してインデックス番号を付与した配列 var textList = extend.list .Select((GUIContent content) => content.text) .Select((string name, int number) => (number + ": \r" + name)) .ToArray();
以上,択一選択式プルダウンメニューにアイコンを設定する方法でした。
(複数選択式プルダウンメニュー MaskField には,アイコンを設定する事は出来ません。)