der*_*ugo 8 c# unity-game-engine unity3d-editor unity-editor
ReorderableList我的CustomEditor脚本中有一个.在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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新
同样apprantly另外,如果我有一个不能正常工作ReorderableList内CustomPropertyDrawer.
但令我惊讶的是,如果我有UnityEvent两件作品:将它放在一个CustomPropertyDrawer或一个内部ReorderableList.我可以按预期添加和删除项目.
正如你在这里看到的,我添加了一个UnityEvent字段
[Serializable]
public class SomeClass
{
public string Name;
public List<SomeClass> InnerList;
}
Run Code Online (Sandbox Code Playgroud)
和使用
//...
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);
Run Code Online (Sandbox Code Playgroud)
并调整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;
}
Run Code Online (Sandbox Code Playgroud)
我可以按预期完全与它进行交互,也可以选择和删除条目.
那么他们在做什么不同呢?
小智 6
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
766 次 |
| 最近记录: |