Locate CustomPropertyDrawer from SerializedObject ?

trying to build the Node Editor based on the others.
I wonder if there is a way to find the PropertyDrawer/PropertyEditor from the SerializedObject.

case:

public TestObject : ScriptableObject { ... }

[CustomPropertyDrawer(typeof(TestObject)]
public TestObjectDrawer : PropertyDrawer { ..... }

//----------------------------
during drawing my Node editor canvas, we use GUILayout.Window() for display those TestObject
since those TestObject can be any scriptableObject, I would like to use the Unity CustomPropertyXXX to display the result.
anyone have idea ? (sorry for English)

1 Like

Welcome to the Dark Side. You’ll need to use Reflection to get the property handler then use Reflection again to get the drawer
Something like this may help:

public class PropertyHandler {

    private static MethodInfo getHandler;
    private static object[] getHandlerParams;

    private object handler;
    private Type type;

    private PropertyInfo propertyDrawerInfo;
    private MethodInfo guiHandler;
    private object[] guiParams;

    public PropertyDrawer propertyDrawer {

        get { return propertyDrawerInfo.GetValue(handler, null) as PropertyDrawer; }
    }

    static PropertyHandler() {

        getHandler = Type.GetType("UnityEditor.ScriptAttributeUtility, UnityEditor").GetMethod("GetHandler", BindingFlags.NonPublic | BindingFlags.Static);
        getHandlerParams = new object[1];
    }

    private PropertyHandler(object handler) {

        this.handler = handler;

        type = handler.GetType();
        propertyDrawerInfo = type.GetProperty("propertyDrawer", BindingFlags.NonPublic | BindingFlags.Instance);
        guiHandler = type.GetMethod("OnGUI", BindingFlags.Public | BindingFlags.Instance);
        guiParams = new object[4];
    }

    public bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren) {

        guiParams[0] = position;
        guiParams[1] = property;
        guiParams[2] = label;
        guiParams[3] = includeChildren;

        return (bool)guiHandler.Invoke(handler, guiParams);
    }

    public static PropertyHandler GetHandler(SerializedProperty property) {

        getHandlerParams[0] = property;

        return new PropertyHandler(getHandler.Invoke(null, getHandlerParams));
    }
}

Check out the “PropertyHandler” class in the UnityEditor namespace if you have DotPeek, lot’s of other useful methods and properties in there. Shame all this stuff is internal, would be very handy.

5 Likes