How to get PropertyAttribute or SerializedProperty owner class instance if it's nested?
Asked Answered
B

2

0

As you see I’ve even tried passing propOwner ( this ) as argument to [MyProperty()], but it’s just stupid. I feel like there is an easy way to get what I want without all these macaroni that I wrote.

public class MyMonoBehaviour: MonoBehaviour //<-- I get instance of this with PropertyDrawer.serializedObject.targetObject
{
    [System.Serializable]public class MyNestedClass
    {
        [MyProperty]public bool myBool;
        //[MyProperty(this)]public bool myBool; //Didn't work
        public void MyMethod(){} //<-- Actually I need to call this
    }
    public MyNestedClass myNestedClassInstance; //<-- But I need this!
  
    void MyMethod(){} //<-- This being called instead
}
public class MyPropertyAttribute: PropertyAttribute
{
    object propOwner; //Can't find any handles here too
    public MyPropertyAttribute(object propOwner = null) //Optional attribute for testing
    {
        this.propOwner = propOwner;
    }
}
[CustomPropertyDrawer(typeof(MyPropertyAttribute))]
public class MyPropertyDrawer: PropertyDrawer
{
    MyPropertyAttribute myPropertyAttribute = (MyPropertyAttribute) attribute; // <-- Found no handles
    Type ownerType = fieldInfo.DeclaringType; //<-- The only thing I've found, but I need instance anyway
  
    string myMethodPath = prop.propertyPath.Replace("."+prop.name, ""); // I've felt so close with this, but it 
    var kindOfWhatINeed = prop.serializedObject.FindProperty(propPath); //returns SerializedProperty and I 
    //can't find any handles to actual instance or Invoke on this directly (but .type shows MyNestedClass)
    
    public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
    {
        if (GUI.Button(position, prop.serializedObject.targetObject)) //<-- Shows MyMonoBehaviour instance
        {
            prop.serializedObject.targetObject.GetType().GetMethod("MyMethod")
                    .Invoke(prop.serializedObject.targetObject); //Invokes MyMethod of MyMonoBehaviour
            //object ownerInstance = prop.owner; <-- I need something like this (returns myNestedClassInstance)
            //ownerType.GetMethod("MyMethod").Invoke(ownerInstance, null); //<-- That's what I want
        }
    }
}
Barbate answered 28/11, 2023 at 11:18 Comment(0)
B
0

While writing this and forming my question better, I found solution here:
https://forum.unity.com/threads/get-a-general-object-value-from-serializedproperty.327098/
It’s even more stupid. I was on the right path, but… “One does not simply get actual SerializedProperty value”. So you need to use sturdy workaround.

Barbate answered 5/7, 2019 at 16:25 Comment(0)
E
0

There is a better solution. Well kind of. Unity’s VisualScripting 1.8 package has
property.GetUnderlyingValue()
which you can use like:
var obj = property.GetUnderlyingValue() as NestedClass;

Found out about it here:
https://forum.unity.com/threads/get-a-general-object-value-from-serializedproperty.327098/page-2#post-9441698

Earnestineearnings answered 26/11, 2023 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.