Unity ReorderableList 可重新排序的列表框使用

可重新排序的列表框

Unity 编辑器内部命名空间有个类 ReorderableList,可以实现通过拖曳来达到列表元素的重新排序,效果如下图所示:
Unity ReorderableList 可重新排序的列表框使用_第1张图片)

基本使用

创建一个测试工程,新建一个脚本文件TestList.cs,代码如下:

using UnityEngine;
using System.Collections.Generic;

public class TestList : MonoBehaviour
{
    public List<string> names = new List<string>();
}

新建一个编辑器脚本文件TestListInspector.cs,代码如下:

using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

[CustomEditor(typeof(TestList))]
public class TestListInspector : Editor 
{
    private ReorderableList m_NameList;

    private void OnEnable()
    {
        m_NameList = new ReorderableList(serializedObject,
            serializedObject.FindProperty("names"),
            true, true, true, true);
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        m_NameList.DoLayoutList();
        serializedObject.ApplyModifiedProperties();
    }
}

附加脚本到物体上,检视器效果如下图所示:
Unity ReorderableList 可重新排序的列表框使用_第2张图片
可以看到列表元素并没有被绘制出来,也不能进行改动。绘制列表元素需要我们自定义如何绘制,在OnEnable函数里面,添加如下代码:

m_NameList.drawElementCallback = DrawNameElement;

添加如下函数:

    private void DrawNameElement(Rect rect, int index, bool selected, bool focused)
    {
        SerializedProperty itemData = m_NameList.serializedProperty.GetArrayElementAtIndex(index);

        rect.y += 2;
        rect.height = EditorGUIUtility.singleLineHeight;
        EditorGUI.PropertyField(rect, itemData, GUIContent.none);
    }

效果如下图所示:
Unity ReorderableList 可重新排序的列表框使用_第3张图片
列表表头显示 Serialized Property,我们将其改成所想要提示的内容。在OnEnable函数里面,添加如下代码:

m_NameList.drawHeaderCallback = (Rect rect) =>
{
    GUI.Label(rect, "Names");
};

效果如下图所示:
这里写图片描述

进阶使用

移除时的警告

在删除元素时,弹出警告对话框,确定之后才能真正删除。在OnEnable函数里面,添加如下代码:

m_NameList.onRemoveCallback = (ReorderableList list) =>
{
    if (EditorUtility.DisplayDialog("警告", "是否真的要删除这个名称?", "是", "否"))
    {
        ReorderableList.defaultBehaviours.DoRemoveButton(list);
    }
};

删除功能调用的是ReorderableList默认行为里的删除功能。效果如下图所示:
Unity ReorderableList 可重新排序的列表框使用_第4张图片

更改添加时的默认值

每次添加新元素时,总是会复制最后一个元素。这里更改其规则,在OnEnable函数里面,添加如下代码:

m_NameList.onAddCallback = (ReorderableList list) =>
{
    if (list.serializedProperty != null)
    {
        list.serializedProperty.arraySize++;
        list.index = list.serializedProperty.arraySize - 1;

        SerializedProperty itemData = list.serializedProperty.GetArrayElementAtIndex(list.index);
        itemData.stringValue = "默认值";
    }
    else
    {
        ReorderableList.defaultBehaviours.DoAddButton(list);
    }
};

效果如下图所示:
Unity ReorderableList 可重新排序的列表框使用_第5张图片

API 文档

构造函数

ReorderableList(
  SerializedObject serializedObject,
  SerializedProperty elements,
  bool draggable,
  bool displayHeader,
  bool displayAddButton,
  bool displayRemoveButton
)

变量

名称 描述
draggable 拖曳排序
displayAdd 显示添加按钮
displayRemove 显示移除按钮
elementHeight 元素高度
headerHeight 表头高度
footerHeight 尾部高度
showDefaultBackground 显示默认背景

公有方法

名称 描述
DoLayoutList 自动布局绘制列表
DoList(Rect rect) 指定区域绘制列表
GetHeight 获取绘制列表总高度

委托

名称 描述
drawHeaderCallback 绘制表头回调
drawFooterCallback 绘制尾部回调
drawElementCallback 绘制元素回调
drawElementBackgroundCallback 绘制元素背景回调
onReorderCallback 重新排序回调
onSelectCallback 选中回调
onAddCallback 添加按钮回调
onAddDropdownCallback 添加下拉选项回调
onRemoveCallback 移除元素回调
onMouseUpCallback 鼠标抬起回调
onCanRemoveCallback 是否显示可移除按钮回调
onChangedCallback 列表改变回调

扩展资料

  1. Unity: make your lists functional with ReorderableList http://va.lent.in/unity-make-your-lists-functional-with-reorderablelist/

你可能感兴趣的:(3.3,Unity)