0
\$\begingroup\$

I've created the MyProperty class to be used on MyBehaviourScript as a public member:

[Serializable]
public class MyProperty
{
    public int Min;
    public int Max;

    public void MyMethod(MyBehaviourScript owner)
    {
        ...
    }
}

I've managed to draw a button in its PropertyDrawer:

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
    EditorGUI.PropertyField(position, property, label, true);
    if (EditorApplication.isPlaying && property.isExpanded)
    {
        if (GUI.Button(new Rect(...), "Text"))
        {
            // todo: call the property's MyMethod method
        }
    }
}

And when I click the property's button:

I'd like to call the property's MyMethod method with its "owner" MyBehaviourScript as a parameter. (I don't know the exact terminology here)

But I don't know how could I get a reference to the property and to its "owner".

Is this possible? If so, how? Thanks!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This seems to do the trick:

[CustomPropertyDrawer(typeof(MyProperty))]
public class MyPropertyDrawer : PropertyDrawer
{
    MyProperty targetProperty;

    public override void OnGUI(
       Rect position,
       SerializedProperty property,
       GUIContent label
    ) {    
        if (targetProperty == null)
             targetProperty = (MyProperty)GetPropertyInstance(property);

        if (GUI.Button(new Rect(position), "Text")) {
            var owner = (MyBehaviourScript)property.serializedObject.targetObject;
            targetProperty.MyMethod(owner);
        }        
    }

    public System.Object GetPropertyInstance(SerializedProperty property) {       

        string path = property.propertyPath;

        System.Object obj = property.serializedObject.targetObject;
        var type = obj.GetType();

        var fieldNames = path.Split('.');
        for (int i = 0; i < fieldNames.Length; i++) {
            var info = type.GetField(fieldNames[i], BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (info == null)
                break;

            // Recurse down to the next nested object.
            obj = info.GetValue(obj);
            type = info.FieldType;            
        }

        return obj;
    }
}

Note however that if you enforce that the argument to MyMethod must always be a MyBehaviourScript, then you can't use this property and its drawer with any type not derived from MyBehaviourScript, so you might be able to implement this more simply as part of a CustomEditor for MyBehaviourScript instead of a PropertyDrawer for the individual property.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .