• Unity编辑器扩展——ReorderableList


    一:前言

    我们定义一个数组或列表,默认是这样显示的

    这样显示有几个缺点
    ——无法改表元素的顺序
    ——如果添加一个元素,需要增加填写size的数值
    ——如果要删除其中一个元素,非常麻烦
    ReorderableList可以让列表或数组在Inspector面板显示得更人性化一些


    二:使用

    首先需要创建一个ReorderableList对象,其中有几个回调函数
    ——drawElementCallback:绘制每个元素的回调
    ——drawHeaderCallback:绘制标题的回调
    ——elementHeightCallback:绘制每个元素的高度的回调
    ——onAddCallback:添加元素时的回调
    ——onRemoveCallback:移除元素时的回调
    最后要调用DoLayoutList方法进行绘制


    三:代码实现—简单案例

    1. using System.Collections.Generic;
    2. using UnityEditor;
    3. using UnityEngine;
    4. using UnityEditorInternal;
    5. using System;
    6. using System.Linq;
    7. public class Test : MonoBehaviour
    8. {
    9. public List<string> list = new List<string>();
    10. }
    11. [CustomEditor(typeof(Test))]
    12. public class TestEditor : Editor
    13. {
    14. SerializedProperty m_list;
    15. ReorderableList reorderableList;
    16. private void OnEnable()
    17. {
    18. m_list = serializedObject.FindProperty("list");
    19. reorderableList = new ReorderableList(serializedObject, m_list, true, true, true, true);
    20. }
    21. public override void OnInspectorGUI()
    22. {
    23. serializedObject.Update();
    24. reorderableList.drawElementCallback = DrawElement;
    25. reorderableList.DoLayoutList();
    26. serializedObject.ApplyModifiedProperties();
    27. }
    28. void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
    29. {
    30. SerializedProperty element = m_list.GetArrayElementAtIndex(index);
    31. EditorGUI.PropertyField(rect, element);
    32. }
    33. }

    四:代码实现—复杂案例

    1. using System.Collections.Generic;
    2. using UnityEditor;
    3. using UnityEngine;
    4. using UnityEditorInternal;
    5. using System;
    6. using System.Linq;
    7. public class Test : MonoBehaviour
    8. {
    9. public List list = new List();
    10. }
    11. [Serializable]
    12. public class TestChild
    13. {
    14. public Sprite sprite;
    15. public string des;
    16. public int index;
    17. }
    18. [CustomEditor(typeof(Test))]
    19. public class TestEditor : Editor
    20. {
    21. SerializedProperty m_list;
    22. ReorderableList reorderableList;
    23. List<float> m_HeightCache = new List<float>();
    24. private void OnEnable()
    25. {
    26. m_list = serializedObject.FindProperty("list");
    27. reorderableList = new ReorderableList(serializedObject, m_list, true, true, true, true);
    28. }
    29. public override void OnInspectorGUI()
    30. {
    31. serializedObject.Update();
    32. reorderableList.onAddCallback = OnAdd;
    33. reorderableList.onRemoveCallback = OnRemove;
    34. reorderableList.onReorderCallback = OnReorder;
    35. reorderableList.onCanRemoveCallback = OnCanRemove;
    36. reorderableList.drawHeaderCallback = DrawHeader;
    37. reorderableList.drawElementCallback = DrawElement;
    38. reorderableList.onSelectCallback = OnSelect;
    39. reorderableList.onAddDropdownCallback = OnAddDropdown;
    40. reorderableList.elementHeightCallback = DrawElementHeight;
    41. reorderableList.DoLayoutList();
    42. serializedObject.ApplyModifiedProperties();
    43. }
    44. void DrawHeader(Rect rect)
    45. {
    46. EditorGUI.LabelField(rect, "Test List");
    47. }
    48. void DrawElement(Rect rect, int index, bool isActive, bool isFocused)
    49. {
    50. m_HeightCache[index] = isActive ? 100 : 50;
    51. SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(index);
    52. SerializedProperty serializedProperty_sprite = element.FindPropertyRelative("sprite");
    53. SerializedProperty serializedProperty_des = element.FindPropertyRelative("des");
    54. SerializedProperty serializedProperty_index = element.FindPropertyRelative("index");
    55. Rect rect_sprite;
    56. Rect rect_des;
    57. Rect rect_index;
    58. if (isActive)
    59. {
    60. rect_sprite = new Rect(rect.x, rect.y, 100, 100);
    61. rect_des = new Rect(rect.x + 120, rect.y, rect.width, 40);
    62. rect_index = new Rect(rect.x + 120, rect.y + 60, rect.width, 40);
    63. }
    64. else
    65. {
    66. rect_sprite = new Rect(rect.x, rect.y, 100, 50);
    67. rect_des = new Rect(rect.x + 120, rect.y, rect.width, 15);
    68. rect_index = new Rect(rect.x + 120, rect.y + 20, rect.width, 15);
    69. }
    70. EditorGUI.PropertyField(rect_sprite, serializedProperty_sprite, GUIContent.none);
    71. EditorGUI.PropertyField(rect_des, serializedProperty_des, GUIContent.none);
    72. EditorGUI.PropertyField(rect_index, serializedProperty_index, GUIContent.none);
    73. }
    74. float DrawElementHeight(int index)
    75. {
    76. if (m_HeightCache.Count > index)
    77. {
    78. return m_HeightCache[index];
    79. }
    80. else
    81. {
    82. m_HeightCache.Add(0);
    83. return m_HeightCache[index];
    84. }
    85. }
    86. void OnAdd(ReorderableList list)
    87. {
    88. if (EditorUtility.DisplayDialog("是否添加", "是否添加", "是", "否"))
    89. {
    90. ReorderableList.defaultBehaviours.DoAddButton(list);
    91. m_HeightCache.Add(0);
    92. }
    93. }
    94. void OnRemove(ReorderableList list)
    95. {
    96. if (EditorUtility.DisplayDialog("是否移除", "是否移除", "是", "否"))
    97. {
    98. ReorderableList.defaultBehaviours.DoRemoveButton(list);
    99. m_HeightCache.RemoveAt(list.count - 1);
    100. }
    101. }
    102. bool OnCanRemove(ReorderableList list)
    103. {
    104. return list.count >= 1;
    105. }
    106. void OnReorder(ReorderableList list)
    107. {
    108. Debug.Log("顺序改变后当前选择元素的index:" + list.index);
    109. }
    110. void OnSelect(ReorderableList list)
    111. {
    112. Debug.Log("当前选择元素的index:" + list.index);
    113. }
    114. void OnAddDropdown(Rect buttonRect, ReorderableList list)
    115. {
    116. var menu = new GenericMenu();
    117. menu.AddItem(new GUIContent("Add Default"), false, clickHandler,
    118. new TestContextParams() { des = "testDes", index = 1, });
    119. menu.ShowAsContext();
    120. }
    121. private void clickHandler(object target)
    122. {
    123. TestContextParams param = (TestContextParams)target;
    124. var index = m_list.arraySize;
    125. m_list.arraySize++;
    126. var element = m_list.GetArrayElementAtIndex(index);
    127. element.FindPropertyRelative("des").stringValue = param.des;
    128. element.FindPropertyRelative("index").intValue = param.index;
    129. serializedObject.ApplyModifiedProperties();
    130. }
    131. struct TestContextParams
    132. {
    133. public string des;
    134. public int index;
    135. }
    136. }

  • 相关阅读:
    HLS基础issue
    「MySQL高级篇」MySQL日志、事务原理 -- undolog、redolog、binlog、两阶段提交
    时间序列(二):单变量回归
    [每日两题系列]刷算法题咯~~
    Flutter教程之 01配置环境并运行demo程序 (教程含源码)
    一篇文章教你搞懂生鲜电商模式
    元数据管理Apache Atlas编译集成部署及测试
    java毕业设计基于精细化考核的离散数学课程教学目标达成系统Mybatis+系统+数据库+调试部署
    华清 Qt day1 9月15
    指针笔试题讲解(让指针变得简单易懂)
  • 原文地址:https://blog.csdn.net/LLLLL__/article/details/126778788