- Home /
Derived Class Serialization
Hi there, first of all i searched all google trying to found a easy fix for this with misleading results.
QUESTION
I have this:
[System.Serializable]
public class ItemModuleData {
}
public class ItemModule {
public ItemModuleData data;
}
[System.Serializable]
public class EquipableData : ItemModuleData {
}
public class EquipableModule : ItemModule {
public new EquipableData data;
}
I want to serialize both classes (ItemModuleData and EquipableData), for do things like this:
ItemModule a;
a.data = anyModuleData;
PROBLEM
Unity can't serialize inherit class, and it will throw an error like this:
The same field name is serialized multiple times in the class or its parent class. This is not supported: Base(MonoBehaviour) data
I can't also use ScriptableObject since i don't want to have a lot of .assets in my project and it makes no sense in this case at least for me.
Thanks in advanced.
Have you tried putting the inheriting classes in their own script files?
Yeah no luck so far. Actually i have them separated.
Answer by Bunny83 · Sep 23, 2016 at 02:51 PM
If you do a quick search about that topic you'll find tons of other questions like those:
I've stopped counting how many times i've answered that question ^^.
In short: Unity does not support inheritance for custom serializable classes. Those classes are not serialized on their own but simply as "child data" of the containing MonoBehaviour / ScriptableObject. The type of an instance is not saved at all. Therefore if you store a derived class in a base class variable it will turn into a base class instance after deserialization.
Likewise since the custom classes aren't stored as seperate instances you can't have cross references. If two MonoBehaviour classes reference the same custom serializable class instance, after deserialization each will have their own instance. Again: Custom serializable classes are just a neat way to manage serialized fields in a MonoBehaviour.
Of course that's only true for Unity's serialization system.
While correct and very useful when originally written and for some time after, this is no longer the case. See my answer below!
Answer by Ruzihm · Mar 10, 2021 at 06:55 AM
The accepted above answer is out of date with the introduction of the SerializeReference decorator. Adding this decorator to the above code will now produce the desired outcome:
[SerializeReference] ItemModule a;
and
[SerializeReference] public ItemModuleData data;
@Ruzihm wow, thank you so much! You've saved me a lot of time.
I feel that I have to speak up right here. First of all, thank you very much @Ruzihm !
I have been searching for this solution for almost a day straight and I only got condescending answers as the accepted one above or C# documentation similarly bot other way condescending saying that not allowing the serialization is to prevent bad design. I personally think that the "user"/programmer should be allowed the freedom of mistake and to learn form it. And perhaps in some cases the solution might not even be bad design but the only solution, and who am I to decide without deep knowledge of the ongoing project.
The other problem I see here is with the Unity community (usually amazing). I mean shouldn't we trace back onto forums where we did not find THE answer and help others? Especially when it comes to an issue that emerges so many times... anyway that's what I'm gonna do, dropping an FYI wherever I didn't find the answer.
Answer by flaviusxvii · Sep 23, 2016 at 03:06 PM
@Bunny83 is correct as usual, but I recently discovered https://github.com/jacobdufault/fullserializer and it is amazing so far. It handles inheritance for you.
Thanks for the answer, in my honest opinion json vs a seralized class it's really slow however maybe i'm wrong!