我有一個自定義編輯器,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);
}
}
這作業正常。但是,我希望此MonoBehaviour編輯的每個實體的 Inspector 都具有相同的元素集,因此我創建了一個ScriptableObject
public MyScriptableObject : ScriptableObject
{
public MyArrayElement[] myList;
}
然后MyComponent.myList用一個實體替換MyScriptableObject
public class MyComponent : MonoBehaviour
{
// Remove this
// public MyArrayElement[] myList;
// Add this
public MyScriptableObject myScriptableObject;
}
然后我想更新我的自定義編輯器MonoBehaviour以顯示myScriptableObject.myList
我試過這個,但檢查器中的串列是空的,即使ScriptableObject的串列不為空
SerializedProperty property = this.serializedObject.FindProperty("myScriptableObject").FindPropertyRelative("myList");
this.list = new ReorderableList(this.serializedObject, property, true, true, true, true);
有沒有辦法讓我的MonoBehaviours 編輯器讓我編輯ScriptableObjects 陣列?
uj5u.com熱心網友回復:
是的,當然有!;)
但首先:從 Unity 2020 開始,不再需要使用ReorderableList,除非您想要一些非常特殊的行為模擬,List<T>而且T[]現在無論如何這是默認的抽屜!
您可能需要考慮CustomPropertyDrawer為您的串列元素 ( MyArrayElement)實作一個特殊的一般情況,以便它實際上以這種方式顯示在您在 Inspector 中公開它的任何地方。
例如例如
[CustomPropertyDrawer(typeof(MyArrayElement))]
public class MyArrayElementDrawer : PropertyDrawer
{
public override int GetPropertyHeight ()
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
// Draw label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
// Calculate rects
var Rect1 = new Rect(position.x, position.y, 100, EditorGUIUtility.singleLineHeight);
var Rect2 = new Rect(position.x 150, position.y, 100, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(Rect1, property.FindPropertyRelative(nameof (MyArrayElement.firstField)), GUIContent.none);
EditorGUI.PropertyField(Rect2, property.FindPropertyRelative(nameof (MyArrayElement.secondField)), GUIContent.none);
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}
然后使用FindPropertyRelative僅適用于[Serializable]類/結構及其子欄位。
每當您處理單獨的UnityEngine.Object參考(另一個MonoBehaviour、ScriptableObject等)時,您需要做的是通過該SerializedObject參考的實體的 。
像例如
var property = serializedObject.FindProperty(nameof(MyComponent.myScriptableObject));
EditorGUILayout.PropertyField(property, true);
if(property.objectReferenceValue)
{
var so = new SerializedObject(property.objectReferenceValue);
so.Update();
var listProperty = so.FindProperty(nameof(MyScriptableObjevt.myList));
EditorGUILayout.PropertyField(listProperty, true);
so.ApplyModifiedProperties();
}
注意:在智能手機上打字,但我希望這個想法變得清晰
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/397770.html
