- Home /
Serialized property and custom class
I want to expose a custom class in the inspector. Using the default editor my class is shown as it should be, but I can't expose it in my custom editor.
I have a abstract class:
[System.Serializable]
public abstract class BaseAbility : IAbility
{
public Team casterTeam;
public float areaOfEffect;
public float cooldown;
public int cost;
protected BaseAbility(Team team, float aoe, float cd, int cost)
{
this.casterTeam = team;
this.areaOfEffect = aoe;
this.cooldown = cd;
this.cost = cost;
}
public abstract void Cast(Vector3 position);
public abstract void Cancel();
}
And another class that is derived from baseAbility:
[System.Serializable]
public class FireAbility : BaseAbility
{
public int damage;
public FireAbility(int damage, Team team, float aoe, float cd, int cost)
: base(team, aoe, cd, cost)
{
this.damage = damage;
}
public override void Cast(Vector3 position)
{
GameObject go = PoolManager.Spawn("FireBall");
Fireball fireball = go.GetComponent<Fireball>();
if (fireball != null)
{
fireball.FireAt(this, position);
}
}
public override void Cancel()
{
}
}
I want to expose FireAbility in the inspector, but for some reason I can't do so. I have a class that has a public FireAbility named fireAbility and in the editor class I do this:
SerializedProperty fireAbility = serializedObject.FindProperty("fireAbility");
EditorGUILayout.PropertyField(fireAbility);
I don't understand why this doesn't work. I have other classes that use custom classes and they just work, but for some reason this doesn't want to.
I don't understand what I'm doing wrong; If I use the default editor it shows my class, but when I use my editor it just shows the toggle arrow and no members. I tried adding [SerializedField], removing the abstract keyword, removing constructors, but nothing worked.
It's certainly interesting, but it's very messy. Since the default editor exposes the class, I guess there must be a way to expose it in a custom editor, but I can't find anything about how the default editor works.
I'm having a similar problem. I have a class which i have custom property drawer. In the custom inspector I receive SerializedProperty which i would like to convert to the original class. I have a already working editor where i can select the method using my EditorWindow. However i would like use the same in the default inspector if my $$anonymous$$onoBehavrious has this property but I'm struggling with the SerializedProperty conversion.
[Serializable]
public class FunctionSelectorProperties
{
public GameObject go;
public $$anonymous$$onoBehaviour functionTarget;
public string methodName;
}
public class OtherClass : ScriptableObject // this is .asset file
{
public string foo;
public int bar;
public FunctionSelectorProperties functionSelector = new FunctionSelectorProperties();
}
[CustomPropertyDrawer(typeof(FunctionSelectorProperties))]
public class FunctionSelectorDrawer : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// ...
FunctionSelectorProperties functionSelector = (FunctionSelectorProperties)property.objectReferenceValue; // cant do this
// ...
}
}
Answer by Statement · Oct 28, 2013 at 02:59 PM
Does the object actually have a "fireAbility" field? Is it exposed as type of IAbility, BaseAbility or FireAbility? It will not work properly if the underlying type is any of the former two.
Try passing true
to the PropertyField.
EditorGUILayout.PropertyField(fireAbility, true);
If true the property including children is drawn; otherwise only the control itself (such as only a foldout but nothing below it).
After a lot of searching I came to think that polymorphism isn't that well supported with the editor classes. Your way seems to be the only one that works, that is using concrete classes only (no abstract classes or interfaces);
You could perhaps have a mechanism for backing storage and create the types and behaviour at runtime though. Or use ScriptableObject, which uses a different serialization logic and allows for polymorphism, though, it adds a little overhead to each object and may not be what you want.