How to select elements in nested ReorderableList in a CustomEditor?

前端 未结 1 1834
天涯浪人
天涯浪人 2020-12-17 23:13

I have a ReorderableList in my CustomEditor script. In the drawElementCallback I added a second nested ReorderableList. Everything wor

相关标签:
1条回答
  • 2020-12-17 23:39

    It looks like you are creating the inner lists over and over without storing them anywhere. I modified your code to store the reorderable lists in a dictionary with the element.propertyPath as a key. Hope this helps.

    using System;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEditorInternal;
    using UnityEngine;
    
    [Serializable]
    public class SomeClass
    {
        public string Name;
        public List<SomeClass> InnerList;
    }
    
    [CreateAssetMenu(menuName = "Example", fileName = "new Example Asset")]
    public class Example : ScriptableObject
    {
        public List<SomeClass> SomeClasses;
    
        [CustomEditor(typeof(Example))]
        private class ModuleDrawer : Editor
        {
            private SerializedProperty SomeClasses;
            private ReorderableList list;
    
            private Dictionary<string, ReorderableList> innerListDict = new Dictionary<string, ReorderableList>();
    
            private void OnEnable()
            {
                SomeClasses = serializedObject.FindProperty("SomeClasses");
    
                // setupt the outer list
                list = new ReorderableList(serializedObject, SomeClasses)
                {
                    displayAdd = true,
                    displayRemove = true,
                    draggable = true,
    
                    drawHeaderCallback = rect =>
                    {
                        EditorGUI.LabelField(rect, "Outer List");
                    },
    
                    drawElementCallback = (rect, index, a, h) =>
                    {
                        // get outer element
                        var element = SomeClasses.GetArrayElementAtIndex(index);
    
                        var InnerList = element.FindPropertyRelative("InnerList");
    
                        string listKey = element.propertyPath;
    
                        ReorderableList innerReorderableList;
    
                        if (innerListDict.ContainsKey(listKey))
                        {
                            // fetch the reorderable list in dict
                            innerReorderableList = innerListDict[listKey];
                        }
                        else
                        {
                            // create reorderabl list and store it in dict
                            innerReorderableList = new ReorderableList(element.serializedObject, InnerList)
                            {
                                displayAdd = true,
                                displayRemove = true,
                                draggable = true,
    
                                drawHeaderCallback = innerRect =>
                                {
                                    EditorGUI.LabelField(innerRect, "Inner List");
                                },
    
                                drawElementCallback = (innerRect, innerIndex, innerA, innerH) =>
                                {
                                    // Get element of inner list
                                    var innerElement = InnerList.GetArrayElementAtIndex(innerIndex);
    
                                    var name = innerElement.FindPropertyRelative("Name");
    
                                    EditorGUI.PropertyField(innerRect, name);
                                }
                            };
                            innerListDict[listKey] = innerReorderableList;
                        }
    
                        // Setup the inner list
                        var height = (InnerList.arraySize + 3) * EditorGUIUtility.singleLineHeight;
                        innerReorderableList.DoList(new Rect(rect.x, rect.y, rect.width, height));
                    },
    
                    elementHeightCallback = index =>
                    {
                        var element = SomeClasses.GetArrayElementAtIndex(index);
    
                        var innerList = element.FindPropertyRelative("InnerList");
    
                        return (innerList.arraySize + 4) * EditorGUIUtility.singleLineHeight;
                    }
                };
            }
    
            public override void OnInspectorGUI()
            {
                serializedObject.Update();
    
                list.DoLayoutList();
    
                serializedObject.ApplyModifiedProperties();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题