- Home /
How to find property of a serializeObject that has the same name with a field of another property?
I had a custom attribute and property drawer class to show or hide field depends on some condition. In the OnGui method of the drawer class, I would find a property and then do something with it.
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
ShowWhenAttribute attribute = (ShowWhenAttribute)this.attribute;
SerializedProperty conditionField = property.serializedObject.FindProperty(attribute.conditionFieldName);
// Do something here
}
I also had a serializable class and an instance of that class in a monobehaviour class.
public enum StatusType { Burn, Bleed, Poison, Freeze, Slow, Blind, Injured }
[System.Serializable]
public class State
{
public StatusType type;
public float duration;
[ShowWhen("duration", /* For example: ">5" */)] public float percent;
public int damage;
public float timeBtwHits;
}
public class Item : MonoBehaviour
{
public float duration;
public State state;
}
The problem is the conditionField
is not state.duration
but duration
. How to fix it?
SerializedProperty has a FindPropertyRelative function. Use FindProperty to find 'state', then use FindPropertyRelative on that to find its 'duration 'property.
You should also use SerializedProperty.Next to loop through all of the properties and print their names just to understand what properties you're accessing.
while (property.Next(true))
Debug.Log(property.name);
Answer by Bunny83 · Oct 25, 2020 at 12:51 PM
Because you used property.serializedObject.FindProperty
. So you accessed the SerializedObject (the root object that is actually serialized, in your case the Item class) and used FindProperty to find a property with that name. If you want to use a property on the "same level" you would need to find the property relative to the parent. Unfortunately the SerializedProperty class doesn't have a GetParent method. However you can create by disecting the property path. Note that this of course has an edge case when you actually have a property inside the root object itself in which case there is no parent serialized property. So I quickly made this FindSiblingProperty extension method:
public static class SerializedPropertyExt
{
public static SerializedProperty GetParent(this SerializedProperty aProperty)
{
var path = aProperty.propertyPath;
int i = path.LastIndexOf('.');
if (i < 0)
return null;
return aProperty.serializedObject.FindProperty(path.Substring(0, i));
}
public static SerializedProperty FindSiblingProperty(this SerializedProperty aProperty, string aPath)
{
var parent = aProperty.GetParent();
if (parent == null)
return aProperty.serializedObject.FindProperty(aPath);
return parent.FindPropertyRelative(aPath);
}
}
With those extension methods you can simply do
SerializedProperty conditionField = property.FindSiblingProperty("condition");
So we first look for a parent property and if there is none we just grab the property on the serialized object. Otherwise we look for the property relative to the parent.
Work well but throw me a compiling error when i try to build my game.
Assets\Scripts\Helper Scripts\SerializedPropertyExt.cs(5,53): error CS0246: The type or namespace name 'SerializedProperty' could not be found (are you missing a using directive or an assembly reference?)
The SerializedObject and SerializedProperty classes are editor only classes. So it should be obvious that this extension class belongs into an editor folder as well, just like any editor code.
My problem was with a "PropertyAttribute" I didn't know it shouldn't be in the Editor folder but now it works, thanks.
Your answer
Follow this Question
Related Questions
SerializedObject.FindProperty returning null 2 Answers
Should EditorGUILayout.PropertyField work with serializable classes? 1 Answer
objectReferenceValue in SerializedProperty 5 Answers
Error when trying to Serialize a field that is in a class 0 Answers
Get SerializedProperty from outside class for use in popup (PropertyDrawer) 1 Answer