我的CustomEditor
脚本中有一个ReorderableList
。在drawElementCallback
中,我添加了第二个嵌套的ReorderableList
。一切正常,我可以在此处将元素添加到两个列表中
但,您会因为某种原因看到我无法选择内部ReorderableList
的元素,因此也无法删除项目。
如何在内部列表中选择项目?
将这些类分解为基本示例
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();
}
}
}
更新
如果我在ReorderableList
中有一个CustomPropertyDrawer
,同样显然也行不通。
但是让我惊讶的是,如果我同时拥有UnityEvent
,那么都可以:将其放在CustomPropertyDrawer
或ReorderableList
中。我可以按预期添加和删除项目。
如您所见,我通过添加
添加了一个UnityEvent
字段
[Serializable]
public class SomeClass
{
public string Name;
public List<SomeClass> InnerList;
}
并使用
//...
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);
并将elementHeightCallback
调整为
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;
}
我可以按预期与之进行完全交互,并且可以选择和删除条目。
那么他们有什么不同?
答案 0 :(得分:2)
似乎您是一遍又一遍地创建内部列表,而没有将它们存储在任何地方。我修改了代码,以<script src="//unpkg.com/lodash/lodash.min.js"></script>
为键将可重排列表存储在字典中。希望这会有所帮助。
element.propertyPath