Can a custom property drawer access other properties?

I am following this Unity - Manual: Create a Custom Inspector to create a custom property drawer for one of my custom controls. I would like the custom property drawer to read the values of other properties. I know I can get the parent property by doing:

            string parentPropertyPath = property.propertyPath[..property.propertyPath.LastIndexOf('.')];
            SerializedProperty parent = property.serializedObject.FindProperty(parentPropertyPath);

and I can see the other properties are in parent’s boxeValue as in:

but I haven’t found a way to read those other properties from the boxedValue. So may questions are: Is it possible? Is there a way to read the values of those other properties?

Unity’s inspector works on serialized data, not directly on the data in the actual objects. Everything you see through SerializedProperty /SerializedObject needs to follow Unity’s serialization rules.

boxedValue gives you the actual underlying object with all its fields. A field existing there does not mean it’s serialized by Unity and accessible as SerializedProperty.

You can either make those fields serialized by Unity or you can access them directly by casting the object boxedValue returns to its actual type. But you will lose all of SerializedProperty’s built-in handling of changes and undo and will have to implement this yourself.

1 Like

Thank you very much for shedding light on my issue. Your reply pointed me in the right direction.

Just for completion and in case someone else has a similar issue and finds this post, what I ended doing was:
1 - Declared in my custom control the property that I needed as [UxmlAttribute] to trigger its serialization, for example:

 public partial class <MyCustomControl> : VisualElement
    {
        [UxmlAttribute, HideInInspector]
        public List<string> MyListOfStrings { get; set; } = new List<string>() {
            "SomeString1",
            "SomeString2",
            "SomeString3",
        };
        // etc.

Note: Since my use-case requires the user not to be able to edit “MyListOfStrings” I also hid it with [HideInInspector] attribute but this is not necessary.

2 - In my custom property drawer I accessed the serialized values by doing:

            List<string> stringValuesFromADifferentProperty = new();
            // Get the SerializedProperty that has the list of strings
            var myListOfStringsPropertyPath = property.propertyPath.Substring(0, property.propertyPath.LastIndexOf('.')) + ".MyListOfStrings";
            var myListOfStringsProperty = property.serializedObject.FindProperty(myListOfStringsPropertyPath);
            // Since the property is a List<string> I have to enumerate the underlying array of strings to get the values
            var stringsEnumerator = myListOfStringsProperty.GetEnumerator();
            while (stringsEnumerator.MoveNext())
            {
                var serializedString = stringsEnumerator.Current as SerializedProperty;
                stringValuesFromADifferentProperty.Add(serializedString.stringValue);
            }
            // That's it!, now I have the list of strings in stringValuesFromADifferentProperty
            foreach (string s in stringValuesInADifferentProperty)
            {
                Debug.Log($"String value from the other property: '{s}'");
                // Do something else with the s string ...
            }

Summarizing: the key part was to add the [UxmlAttribute] attribute to the property in my custom control so that it becomes a SerializedProperty that is accessible in the custom property drawer (this can be verified by watching the boxedValue in the debugger).

1 Like

We did also have an example of doing this in the docs. See MyDrawerAttributePropertyDrawer .

1 Like