I have a ReorderableList
in my CustomEditor
script. In the drawElementCallback
I added a second nested ReorderableList
. Everything works fine and I can add elements to both lists like here
BUT as you can see for some reason I can not select the elements of the inner ReorderableList
s so I also can not remove items.
How can I select items in the inner list?
Here the classes broken down to the basic example
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 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");
// Setup the inner list
var 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);
}
};
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();
}
}
}
Update
The same apprantly also doesn't work if I have a ReorderableList
within a CustomPropertyDrawer
.
But to my suprise if I have a UnityEvent
both works: Having it inside a CustomPropertyDrawer
or within a ReorderableList
. I can add and remove items as expected.
As you can see here I added a UnityEvent
field by adding
[Serializable]
public class SomeClass
{
public string Name;
public List<SomeClass> InnerList;
}
and using
//...
innerReorderableList.DoList(new Rect(rect.x, rect.y, rect.width, height));
var InnerEvent = element.FindPropertyRelative("InnerEvent");
var pers = InnerEvent.FindPropertyRelative("m_PersistentCalls.m_Calls");
var evHeight = (Mathf.Max(1, pers.arraySize) * 2 + 3) * EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, evHeight), InnerEvent);
and adjusting the elementHeightCallback
to
elementHeightCallback = index =>
{
var element = SomeClasses.GetArrayElementAtIndex(index);
var innerList = element.FindPropertyRelative("InnerList");
var InnerEvent = element.FindPropertyRelative("InnerEvent");
var pers = InnerEvent.FindPropertyRelative("m_PersistentCalls.m_Calls");
return (Mathf.Max(1, innerList.arraySize) + 4 + Mathf.Max(1, pers.arraySize) * 2 + 4) * EditorGUIUtility.singleLineHeight;
}
I can fully interact with it as expected and also select and remove entries.
So what are they doing different?
See Question&Answers more detail:
os