I’m trying to update how the elements in one entry of an array are displayed, depending on the elements in that array, using the UIToolkit Custom property drawer.
A simplified version of my SO, with an Entry[ ]:
public class EquipmentCardSO : CardSO
{
[Serializable]
public enum Effect
{
None, Heal
}
[Serializable]
public class Entry
{
public Effect effect;
public int healAmount;
}
public Entry[] entries;
}
What I want to do is create a Custom Property Drawer such that the healAmount property for an entry only displays if the effect is set to Heal.
I’ve gotten most of the way there with the following:
[CustomPropertyDrawer(typeof(EquipmentCardSO.Entry))]
public class EquipmentCardEntryPropertyDrawer : PropertyDrawer
{
private VisualElement _healAmount;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var root = new VisualElement();
var effect = new PropertyField(property.FindPropertyRelative("effect"));
effect.RegisterValueChangeCallback(EffectChanged);
root.Add(effect);
_healAmount = new PropertyField(property.FindPropertyRelative("healAmount"));
root.Add(_healAmount);
RemoveAllFields();
return root;
}
private void EffectChanged(SerializedPropertyChangeEvent evt)
{
RemoveAllFields();
switch ((EquipmentCardSO.Effect)evt.changedProperty.intValue)
{
case EquipmentCardSO.Effect.Heal:
_healAmount.style.display = DisplayStyle.Flex;
break;
}
}
private void RemoveAllFields()
{
_healAmount.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
}
But the problem is, in the EffectChanged callback, I can’t find a way to determine if it is this instance of the inspector whose effect property changed. So, if there are several array elements added, and one effect is changed to Heal, it may or may not cause the healAmount field to appear on that particular entry in the array - instead, it might appear elsewhere. Likewise, changing an array elements effect to none, may cause another entry to lose its healAmount field. Adding or removing elements also has this effect.
On the other hand if I use this:
[CustomPropertyDrawer(typeof(EquipmentCardSO.Entry))]
public class EquipmentCardEntryPropertyDrawer : PropertyDrawer
{
private VisualElement _healAmount;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var root = new VisualElement();
var effect = new PropertyField(property.FindPropertyRelative("effect"));
root.Add(effect);
_healAmount = new PropertyField(property.FindPropertyRelative("healAmount"));
root.Add(_healAmount);
RemoveAllFields();
switch ((EquipmentCardSO.Effect)property.FindPropertyRelative("effect").intValue)
{
case EquipmentCardSO.Effect.Heal:
_healAmount.style.display = DisplayStyle.Flex;
break;
}
return root;
}
private void RemoveAllFields()
{
_healAmount.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
}
}
Adding or removing elements updates each entry as would be expected for its assigned effect, but changing an individual entry’s effect doesn’t cause an update.
Is there a good way to solve this issue?