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:
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.
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).