我们定义一个数组或列表,默认是这样显示的
这样显示有几个缺点
——无法改表元素的顺序
——如果添加一个元素,需要增加填写size的数值
——如果要删除其中一个元素,非常麻烦
ReorderableList可以让列表或数组在Inspector面板显示得更人性化一些
首先需要创建一个ReorderableList对象,其中有几个回调函数
——drawElementCallback:绘制每个元素的回调
——drawHeaderCallback:绘制标题的回调
——elementHeightCallback:绘制每个元素的高度的回调
——onAddCallback:添加元素时的回调
——onRemoveCallback:移除元素时的回调
最后要调用DoLayoutList方法进行绘制

- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- using UnityEditorInternal;
- using System;
- using System.Linq;
-
- public class Test : MonoBehaviour
- {
- public List<string> list = new List<string>();
- }
-
- [CustomEditor(typeof(Test))]
- public class TestEditor : Editor
- {
- SerializedProperty m_list;
-
- ReorderableList reorderableList;
-
- private void OnEnable()
- {
- m_list = serializedObject.FindProperty("list");
- reorderableList = new ReorderableList(serializedObject, m_list, true, true, true, true);
- }
-
- public override void OnInspectorGUI()
- {
- serializedObject.Update();
-
- reorderableList.drawElementCallback = DrawElement;
- reorderableList.DoLayoutList();
-
- serializedObject.ApplyModifiedProperties();
- }
-
- void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
- {
- SerializedProperty element = m_list.GetArrayElementAtIndex(index);
- EditorGUI.PropertyField(rect, element);
- }
- }

- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- using UnityEditorInternal;
- using System;
- using System.Linq;
-
- public class Test : MonoBehaviour
- {
- public List
list = new List(); - }
-
- [Serializable]
- public class TestChild
- {
- public Sprite sprite;
- public string des;
- public int index;
- }
-
- [CustomEditor(typeof(Test))]
- public class TestEditor : Editor
- {
- SerializedProperty m_list;
-
- ReorderableList reorderableList;
-
- List<float> m_HeightCache = new List<float>();
-
- private void OnEnable()
- {
- m_list = serializedObject.FindProperty("list");
- reorderableList = new ReorderableList(serializedObject, m_list, true, true, true, true);
- }
-
- public override void OnInspectorGUI()
- {
- serializedObject.Update();
-
- reorderableList.onAddCallback = OnAdd;
- reorderableList.onRemoveCallback = OnRemove;
- reorderableList.onReorderCallback = OnReorder;
- reorderableList.onCanRemoveCallback = OnCanRemove;
- reorderableList.drawHeaderCallback = DrawHeader;
- reorderableList.drawElementCallback = DrawElement;
- reorderableList.onSelectCallback = OnSelect;
- reorderableList.onAddDropdownCallback = OnAddDropdown;
- reorderableList.elementHeightCallback = DrawElementHeight;
- reorderableList.DoLayoutList();
-
- serializedObject.ApplyModifiedProperties();
- }
-
- void DrawHeader(Rect rect)
- {
- EditorGUI.LabelField(rect, "Test List");
- }
-
- void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
- {
- m_HeightCache[index] = isActive ? 100 : 50;
-
- SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(index);
-
- SerializedProperty serializedProperty_sprite = element.FindPropertyRelative("sprite");
- SerializedProperty serializedProperty_des = element.FindPropertyRelative("des");
- SerializedProperty serializedProperty_index = element.FindPropertyRelative("index");
-
- Rect rect_sprite;
- Rect rect_des;
- Rect rect_index;
- if (isActive)
- {
- rect_sprite = new Rect(rect.x, rect.y, 100, 100);
- rect_des = new Rect(rect.x + 120, rect.y, rect.width, 40);
- rect_index = new Rect(rect.x + 120, rect.y + 60, rect.width, 40);
- }
- else
- {
- rect_sprite = new Rect(rect.x, rect.y, 100, 50);
- rect_des = new Rect(rect.x + 120, rect.y, rect.width, 15);
- rect_index = new Rect(rect.x + 120, rect.y + 20, rect.width, 15);
- }
-
- EditorGUI.PropertyField(rect_sprite, serializedProperty_sprite, GUIContent.none);
- EditorGUI.PropertyField(rect_des, serializedProperty_des, GUIContent.none);
- EditorGUI.PropertyField(rect_index, serializedProperty_index, GUIContent.none);
- }
-
- float DrawElementHeight(int index)
- {
- if (m_HeightCache.Count > index)
- {
- return m_HeightCache[index];
- }
- else
- {
- m_HeightCache.Add(0);
- return m_HeightCache[index];
- }
- }
-
- void OnAdd(ReorderableList list)
- {
- if (EditorUtility.DisplayDialog("是否添加", "是否添加", "是", "否"))
- {
- ReorderableList.defaultBehaviours.DoAddButton(list);
- m_HeightCache.Add(0);
- }
- }
-
- void OnRemove(ReorderableList list)
- {
- if (EditorUtility.DisplayDialog("是否移除", "是否移除", "是", "否"))
- {
- ReorderableList.defaultBehaviours.DoRemoveButton(list);
- m_HeightCache.RemoveAt(list.count - 1);
- }
- }
-
- bool OnCanRemove(ReorderableList list)
- {
- return list.count >= 1;
- }
-
- void OnReorder(ReorderableList list)
- {
- Debug.Log("顺序改变后当前选择元素的index:" + list.index);
- }
-
- void OnSelect(ReorderableList list)
- {
- Debug.Log("当前选择元素的index:" + list.index);
- }
-
- void OnAddDropdown(Rect buttonRect, ReorderableList list)
- {
- var menu = new GenericMenu();
- menu.AddItem(new GUIContent("Add Default"), false, clickHandler,
- new TestContextParams() { des = "testDes", index = 1, });
- menu.ShowAsContext();
- }
-
- private void clickHandler(object target)
- {
- TestContextParams param = (TestContextParams)target;
- var index = m_list.arraySize;
- m_list.arraySize++;
- var element = m_list.GetArrayElementAtIndex(index);
- element.FindPropertyRelative("des").stringValue = param.des;
- element.FindPropertyRelative("index").intValue = param.index;
- serializedObject.ApplyModifiedProperties();
-
- }
- struct TestContextParams
- {
- public string des;
- public int index;
- }
- }