I have a custom serializable class as a field of my component and I created a property drawer for it like:
[Serializable]
public class MyInnerClass
{
public int value;
}
[Serializable]
public class MyClass
{
public int value;
public MyInnerClass innerValue;
}
public class MyComponent : MonoBehaviour
{
[SerializedField]
public MyClass data;
}
[CustomPropertyDrawer(typeof(MyClass))]
public class MyClassDrawer : PropertyDrawer
{
}
And when I add more than one MyComponent into the scene I want add a context menu to the MyClassDrawer which could do a copy/paste function so I can copy the values on one MyClass to another.
And here are my questions:
In the MyClassDrawer I can only handle the SerializedProperty but the SerializedProperty doesn’t provide an interface to CopyFrom others.
I’m looking for a generic solution to copy to/from between SerializedProperty without get into the details of each class to copy the fields one by one.
It seems when implementing the custom PropertyDrawer by overriding OnGUI() using EditorGUI.BeginProperty / EditorGUI.EndProperty() you get prefab override logic and the right click copy context menu for free.
(I found out just by using the example code from the PropertyDrawer documentation page).
This is the code I tested this with:
Code
using System;
using UnityEditor;
using UnityEngine;
public class MyComponent : MonoBehaviour {
[SerializeField]
public MyClass data;
}
[Serializable]
public class MyInnerClass {
public int value;
}
[Serializable]
public class MyClass {
public int value;
public MyInnerClass innerValue;
}
[CustomPropertyDrawer(typeof(MyClass))]
public class MyClassDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
// Draw label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Calculate rects
var value = new Rect(position.x, position.y, 30, position.height);
var innerValue = new Rect(position.x + 35, position.y, 50, position.height);
// Draw fields - passs GUIContent.none to each so they are drawn without labels
EditorGUI.PropertyField(value, property.FindPropertyRelative("value"), GUIContent.none);
EditorGUI.PropertyField(innerValue, property.FindPropertyRelative("innerValue.value"), GUIContent.none);
EditorGUI.EndProperty();
}
}
Yeah, but I want to create custom property drawers, so, right now they don’t support it, if add a custom label they don’t work as they did when using IMGUI.
UIElements are great when dealing with “meta” stuff, but if you’re doing a single element that can be used in both IMGUI and UIElement contexts, it’s still better to use IMGUI