[英]Can I create a custom MonoBehaviour editor to edit a list from a ScriptableObject field?
I have a custom editor for a MonoBehaviour
to display a reorderable list of items.我有一个MonoBehaviour
的自定义编辑器来显示可重新排序的项目列表。
public class MyComponent : MonoBehaviour
{
public MyArrayElement[] myList;
}
public struct MyArrayElement
{
public string firstField;
public string secondField;
}
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
private ReorderableList list;
private void OnEnable()
{
SerializedProperty property = this.serializedObject.FindProperty("myList");
this.list = new ReorderableList(this.serializedObject, property, true, true, true, true);
list.drawElementCallback = DrawListItems;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
list.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
{
EditorGUI.PropertyField(
new Rect(rect.x, rect.y, 100, EditorGUIUtility.singleLineHeight),
element.FindPropertyRelative("firstField"),
GUIContent.none);
EditorGUI.PropertyField(
new Rect(rect.x + 150, rect.y, 100, EditorGUIUtility.singleLineHeight),
element.FindPropertyRelative("secondField"),
GUIContent.none);
}
}
This works correctly.这可以正常工作。 However, I would like to have the Inspector for every instance of this MonoBehaviour
edit the same set of elements, so I created a ScriptableObject
但是,我想让这个MonoBehaviour
的每个实例的 Inspector 编辑相同的元素集,所以我创建了一个ScriptableObject
public MyScriptableObject : ScriptableObject
{
public MyArrayElement[] myList;
}
And then replace MyComponent.myList
with an instance of MyScriptableObject
然后用MyScriptableObject
的实例替换MyComponent.myList
public class MyComponent : MonoBehaviour
{
// Remove this
// public MyArrayElement[] myList;
// Add this
public MyScriptableObject myScriptableObject;
}
Then I want to update my custom editor for the MonoBehaviour
to show myScriptableObject.myList
然后我想更新MonoBehaviour
的自定义编辑器以显示myScriptableObject.myList
I tried this, but the list is empty in the Inspector, even if the ScriptableObject
's list is not empty我试过了,但检查器中的列表是空的,即使ScriptableObject
的列表不为空
SerializedProperty property = this.serializedObject.FindProperty("myScriptableObject").FindPropertyRelative("myList");
this.list = new ReorderableList(this.serializedObject, property, true, true, true, true);
Is there a way to get my MonoBehaviour
s editor to let me edit the ScriptableObject
s array?有没有办法让我的MonoBehaviour
的编辑器让我编辑ScriptableObject
的数组?
Yes there is;就在这里; ;) ;)
But first of all: Starting with Unity 2020 there is no need to use ReorderableList
anymore except you want some very special behavior which seems not to be the case here.但首先:从 Unity 2020 开始,不再需要使用ReorderableList
,除非您想要一些非常特殊的行为,而这里似乎并非如此。 For List<T>
and T[]
this is now the default drawer anyway!对于List<T>
和T[]
无论如何,这现在是默认抽屉!
And then using FindPropertyRelative
only works for [Serializable]
classes.然后使用FindPropertyRelative
仅适用于[Serializable]
类。
Whenever you deal with a separate UnityEngine.Object
what you need to do is go through the SerializedObject
of the instance of that reference.每当您处理单独的UnityEngine.Object
,您需要做的是通过该引用实例的SerializedObject
进行 go。
Like eg像例如
var property = serializedObject.FindProperty("myScriptableObject").FindPropertyRelative("myList");
EditorGUILayout.PropertyField(property, true);
if(property.objectReferenceValue)
{
var so = new SerializedObject(property.objectReferenceValue);
so.Update();
var list = so.FindProperty("myList");
EditorGUILayout.PropertyField(list, true);
so.ApplyModifiedProperties();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.