ReorderableList
を使うと、Unity組込みのインスペクタでよくあるこんな感じのUIを独自のクラスに適用することができます。
例えば、以下のようなクラスが定義されていて、HogeList
というプロパティをインスペクタ上で順番変更したいとする
Hoge.cs
public class Hoge : MonoBehaviour {
public List<string> HogeList;
// ... snip ...
}
以下のようにカスタムエディタを定義する
HogeEditor.cs
using UnityEditor;
using UnityEditorInternal;
[CustomEditor(typeof(Hoge))]
public class HogeEditor : Editor {
ReorderableList m_list;
void OnEnable() {
m_list = new ReorderableList (
serializedObject,
serializedObject.FindPropertyRelative("HogeList")
);
}
// 変更可能なリストを表示
public override void OnInspectorGUI () {
// とりあえず元のプロパティ表示はしておく
DrawDefaultInspector();
serializedObject.Update ();
// リスト・配列の変更可能なリストの表示
m_list.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
以上が最低限の実装
ヘッダの文字を変更するには、OnEnable()
に以下を追加
HogeEditor(1).cs
m_list.drawHeaderCallback = (rect) => {
EditorGUI.LabelField(rect, "ほげほげ一覧");
};
リストの個々の要素の描画内容を変更するには以下を追加
HogeEditor(2).cs
m_list.drawElementCallback = (rect, index, isActive, isFocused) => {
var motion = m_motionsList.serializedProperty.GetArrayElementAtIndex(index);
var displayName = string.Format ("{0} : {1}",
motion.FindPropertyRelative("Name").intValue,
motion.FindPropertyRelative("Age").stringValue
);
EditorGUI.LabelField(rect, displayName);
};
Tips
1行の高さを変更する
// 2行分の高さに設定する
m_list.elementHeight = EditorGUIUtility.singleLineHeight * 2;
drawElementCallback の中で配列の要素にアクセスする
// callbackが呼び出されるときに渡される index を使って配列の要素を取得
var element = m_list.serializedProperty.GetArrayElementAtIndex(index);
// 配列の要素の"Name"プロパティの値を取得
var name = element.FindPropertyRelative("Word");
// ラベルを描画
EditorGUI.LabelField(rect, string.Format ("{0}:{1}", index, name.stringValue));