Hello,
Recently I updated a lot of outdated lines of code in my project, but now I got an inheritance problem, and I don’t know how to fix it :
I declare a CharacterStatSheet object in my Character class ( abstract class ), this object is set in childs of this class ( monster / player )
In Monster class the CharacterStatSheet is supposed to be a MonsterStatSheet object, but it seems like it’s not the case it’s a CharacterStatSheet object.
( here is the lines )
public abstract class Character : MonoBehaviour {
public CharacterStatSheet charStatSheet;
protected virtual void Reset()
{
[...]
}
[...]
}
public class Monster : Character {
protected override void Reset()
{
charStatSheet = new MonsterStatSheet();
}
}
Any idea ?
Thanks a lot, i’ll test as soon as possible !
Bunny83
5
Unity’s serializer does not support inheritance for custom serializable classes. Please read the script serialization documentation page carefully. Especially the section labelled
When might the serializer behave
unexpectedly?
Polymorphism is only supported for MonoBehaviour or ScriptableObject derived types. Custom serializable classes behave like structs and are serialized inline based on the variable / field type. Since your field has the type “CharacterStatSheet” it will always be serialized as CharacterStatSheet, no matter what you assign to this field.
If you want to better understand how Unity serializes your objects, i recommend setting your asset serialization mode to “force text” (which i think is now already the default) and open the serialized asset (prefab or scene file) in a simple text editor. An editor that has YAML highlighting would be recommended.
You may also want to look through the sub categories of the text-based scene files which roughly explain the YAML format and provide a list of type IDs which makes it easier to understand and navigate such a YAML file. If you inspect your serialized object you will notice that custom serializable classes do not store any type information. The serializable fields are just serialized as sub fields.
you could do something like
public abstract class Character : MonoBehaviour
{
protected CharacterStatSheet charStatSheet;
public CharacterStatSheet CharStatSheet { get { return (CharacterStatSheet)charStatSheet; } }
protected virtual void Reset()
{
[...]
}
[...]
}
then
public class Monster : Character {
public new MonsterStatSheet CharStatSheet { get { return (MonsterStatSheet)charStatSheet; } }
protected override void Reset()
{
//dont really need this anymore you can just get the public CharStatSheet
//charStatSheet = new MonsterStatSheet();
}
}
This should work if MonsterStatSheet is a member of CharacterStatSheet
MonsterStatSheet must inherits from CharacterStatSheet. Your charStatSheet is instance of CharacterStatSheet and you assign MonsterStatSheet instance. When you run charStatSheet instance’s visual methods, the methods which is overided by MonsterStatSheet class run. But If a method of MonsterStatSheet class is not overrided method of CharacterStatSheet, you can’t call this from CharacterStatSheet class’ instance.