- Home /
Properly serialize array of derived classes.
Consider the following situation:
[System.Serializable]
public class CustomClassBase
{
...
}
[System.Serializable]
public class CustomClassA: CustomClassBase
{
...
}
[System.Serializable]
public class CustomClassB: CustomClassBase
{
...
}
public class CustomComponent: MonoBehavior
{
public CustomClassBase[] customClasses;
}
If customClasses contains instances of both CustomClassA and CustomClassB, is there anyway to make sure the customClasses gets serialized properly? I've tried using Object as a base class, and I'd rather not use ScriptableObject, due to the file name restriction. If there isn't a solution, can anyone think of a way to get around the problem?
Answer by Bunny83 · Feb 26, 2013 at 12:03 AM
I answered the same question a couple of times, however i can't find one at the moment ^^
Unfortunately Unity doesn't support inheritance in custom classes when it comes to serialization. Unity can only serialize it's own types eg, types derived from UnityEngine.Object, most native types (int, float, string, ...) and some special types like Vector2/3/4, NetworkViewID, Quaternion, ... . The only classes you can use to derive your own classes from are MonoBehaviour and ScriptableObject.
MonoBehaviours can be part of a scene serialization, so when it's attached to an object in a scene, or as part of a prefab / asset serialization. ScriptableObjects can only be serialized as assets. These types can be serialized on it's own.
Custom serializable classes (classes with the System.Serializable attribute) are serialized along with a referencing MonoBehaviour or ScriptableObject. This behaves more like a struct-relationship. The custom class becomes a part of the MonoBehaviour / ScriptableObject.
Unity serialized / deserializes those classes based on the variable type that references the class. So if your MonoBehaviour contains a List of CustomClassBase references, all instances will be serialized / deserialized as CustomClassBase.
Unity serializes custom classes into the referencing MonoBehaviour, so when you have an instance of your custom class and have two or more references in MonoBehaviour classes to this instance, you will end up with multiple seperate instances upon deserialization.
The only way to support inheritance is to use MonoBehaviours or ScriptableObjects. ScriptableObjects are usually the first choice, however they need to be saved as an asset, so there's some editor code required. MonoBehaviours can easily put on scene objects or saved along with prefabe (might also require some editor code).
Keep in mind that every UnityEngine.Object has hideFlags which are quite handy when it comes to hide certain objects or to prevent the serialization of temporal scene objects. The best example is the SceneView camera. You'll never see the camera but it's attached to an invisible GameObject in the scene. This GO and all it's components are marked with HideAndDontSave
Thanks for the breakdown. I wish Unity provided this much information in its official documentation.
Thanks, as said by TheOrange$$anonymous$$an, this is cleary the kind of information we need to find in Unity official documentation. What a pity they don't work on it to include such essential piece of info.
Answer by kornel-l-varga · Apr 22, 2021 at 11:22 AM
I have found a great answer (not the accepted one) here by @Ruzihm : https://answers.unity.com/questions/1247233/derived-class-serialization.html
Use the [SerializeReference] decorator on the fields you want to keep their derivate values and type.
Answer by nventimiglia · Feb 24, 2013 at 01:43 AM
If you derive from abstract class, the class does not 'contain' the class it derives from. it 'is' the class it derives from.
Try using the [SerializeField] attribute on the customClassess property.
I've tried [SerializeField]. I think you misunderstood what I meant when I said 'contain'. I was referring to the array, not to the classes.
Answer by Xarbrough · Sep 19, 2015 at 11:42 PM
The question has been answered, but Unity does provide the necessary information: Manual - Script Serialization
There are also a couple of videos recordings from Unity developers which talk about the issue live. Just google for Unity Serialization In-Depth and related videos from Unite Conference.