Inheritance, List and CustomPropertyDrawer
Hi Everyone, This is my first question here, and I usually prefer to try and search for a solution myself, but this time I've been stuck for a few hours and I'm sure I either do something wrong, or just miss a simple tip to go in the right direction.
Here is my problem:
I have an Object (Spell) that contains a List of Effect. An Effect can be anything, but consider that I have 3 possibles Effects : Heal, Damage, Armor.
I have something that look like this for my spell :
public class Spell : ScriptableObject
{
public string Name;
public int Cost;
...
public List<Effect> Effects;
}
And my effects all inherit from a BaseClass Effect :
public class Effect
{
public int Value;
...
}
public class DamageEffect : Effect
{
public bool IgnoreArmor;
public bool CanCrit;
...
}
Now my issue is that I want to display my Effect list with a custom Editor, and I want each Effect to appear differently in the custom editor. It seems I can use CustomPropertyDrawers for each of my effects, and that works well... when I'm not using a List.
Since I'm using a List, I somehow want it to display my Effect using the specialized PropertyDrawer.
Currently my PropertyDrawer looks like that :
// DamageEffectDrawer
[CustomPropertyDrawer(typeof(DamageEffect))]
public class DamageEffectDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);
EditorGUILayout.LabelField("Damage Effect", EditorStyles.whiteLabel);
EditorGUILayout.PropertyField(property.FindPropertyRelative("Value"));
EditorGUILayout.PropertyField(property.FindPropertyRelative("IgnoreArmor"));
...
EditorGUI.EndProperty();
}
}
And my CustomEditor for Spells looks like that :
[CustomEditor(typeof(Spell))]
public class SpellCustomEditor : Editor
{
private eEffectType _effectToAdd = eEffectType.Unknown;
override public void OnInspectorGUI()
{
var spell = target as Spell;
EditorGUI.BeginChangeCheck();
SerializedObject spellObject = new UnityEditor.SerializedObject(spell);
EditorGUILayout.LabelField("General Options", EditorStyles.boldLabel);
spell.Name = EditorGUILayout.TextField("Spell Name : ", spell.Name);
spell.Cost = EditorGUILayout.IntField("Spell Cost : ", spell.Cost);
....
EditorGUILayout.LabelField("Effects : ", EditorStyles.boldLabel);
_effectToAdd = (eEffectType)EditorGUILayout.EnumPopup("Effect Type : ", _effectToAdd);
if (GUILayout.Button("Add effect"))
{
spell.AddEffect(_effectToAdd);
}
for (int i =0; i < spell.Effects.Count; i++)
{
SerializedProperty myEffect = spellObject.FindProperty("Effects").GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(myEffect);
if (GUILayout.Button("Remove effect"))
{
spell.RemoveEffect(i);
}
}
if (EditorGUI.EndChangeCheck())
{
spellObject.ApplyModifiedProperties();
}
EditorUtility.SetDirty(target);
}
}
I get in trouble when I do EditorGUILayout.PropertyField(myEffect); Obviously at this point it only knows it's an Effect, and so doesn't display it as a DamageEffect (or whatever).
Does anyone has a smart suggestion on how I could handle that? Maybe I went completely in the wrong direction in the first place.
Thank you for reading, and for any suggestion you might have. Have a nice evening !