ReorderableListの使い方です。
Unity2018.3.1
ReorderableList?
ReordearableList
は並べ替え可能なリストをエディタで表示するためにUnityが用意しているクラスです。
こんな感じの見た目が簡単に作れます。
使い方(EditorGUILayout環境で使う)
使い方は簡単です。
using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditorInternal; public class Example : MonoBehaviour { [SerializeField] private List<int> _exampleList; } [CustomEditor(typeof(Example))] public class ExampleEditor : Editor { private ReorderableList _reorderableList; public override void OnInspectorGUI() { serializedObject.Update(); var listProp = serializedObject.FindProperty("_exampleList"); // ReorderableListを作る if (_reorderableList == null) { _reorderableList = new ReorderableList(serializedObject, listProp); } // 描画 _reorderableList.DoLayoutList(); serializedObject.ApplyModifiedProperties(); } }
ReorderableList
のコンストラクタにserializedObjectとリストのserializedPropertyを渡すだけです。
あとはDoLayoutList()
で描画されます。
結果は次のようになります。
いろんな設定
ReorderableListのプロパティやコールバックにアクセスするといろんな設定ができます。
タイトル部分や要素部分をカスタムできます。
[CustomEditor(typeof(Example))] public class ExampleEditor : Editor { private ReorderableList _reorderableList; public override void OnInspectorGUI() { serializedObject.Update(); var listProp = serializedObject.FindProperty("_exampleList"); if (_reorderableList == null) { _reorderableList = new ReorderableList(serializedObject, listProp); // 並び替え可能か _reorderableList.draggable = false; // タイトル描画時のコールバック // 上書きしてEditorGUIを使えばタイトル部分を自由にレイアウトできる _reorderableList.drawHeaderCallback = rect => EditorGUI.LabelField(rect, "Title"); // プロパティの高さを指定 _reorderableList.elementHeightCallback = index => 30; // 要素の描画時のコールバック // 上書きしてEditorGUIを使えば自由にレイアウトできる _reorderableList.drawElementCallback = (rect, index, isActive, isFocused) => { var elementProperty = listProp.GetArrayElementAtIndex(index); rect.height = EditorGUIUtility.singleLineHeight; EditorGUI.PropertyField(rect, elementProperty, new GUIContent("要素" + index)); }; // +ボタンが押された時のコールバック _reorderableList.onAddCallback = list => Debug.Log("+ clicked."); // -ボタンが押された時のコールバック _reorderableList.onRemoveCallback = list => Debug.Log("- clicked : " + list.index + "."); } _reorderableList.DoLayoutList(); serializedObject.ApplyModifiedProperties(); } }
主要な項目だけ設定してみました。
結果は次のようになります。
EditorGUI環境で使う
ここまでの例はEditorGUILayout
環境でReorderableList
を使ってきました。
EditorGUI
環境でこれを使うためには、描画時にDoLayoutList()
の代わりにDoList()
メソッドを使います。
たとえばPropertyDrawerに使うとこんな感じです。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditorInternal; public class Example : MonoBehaviour { [System.Serializable] public class Example2 { [SerializeField] private List<int> _exampleList; } [SerializeField] private Example2 _example2; } [CustomPropertyDrawer(typeof(Example.Example2))] public class PostalCodeDrawer : PropertyDrawer { private class PropertyData { public SerializedProperty exampleListProperty; public ReorderableList reorderableList; } private Dictionary<string, PropertyData> _propertyDataPerPropertyPath = new Dictionary<string, PropertyData>(); private PropertyData _property; private float LineHeight { get { return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } } private void Init(SerializedProperty property) { if (_propertyDataPerPropertyPath.TryGetValue(property.propertyPath, out _property)){ return; } _property = new PropertyData(); _property.exampleListProperty = property.FindPropertyRelative("_exampleList"); // ReorderableListを初期化 var reorderableList = new ReorderableList(property.serializedObject, _property.exampleListProperty); _property.reorderableList = reorderableList; _propertyDataPerPropertyPath.Add(property.propertyPath, _property); } public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { Init(property); var fieldRect = position; fieldRect.height = LineHeight; using (new EditorGUI.PropertyScope(fieldRect, label, property)) { // プロパティを描画 // EditorGUI環境の場合はDoListを使う _property.reorderableList.DoList(fieldRect); } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { Init(property); // ReorderableListの高さを取得する return _property.reorderableList.GetHeight(); } }
結果は次のようになります。