Can a custom Inspector serialize a List<> of derived classes?

I'm creating a custom inspector for one of the monobehaviour components in my game.

This class stores a List of behaviors that derive from a base behavior. These behaviors are marked serializable, and the custom editor is wired up to show the list of these derived behaviors and their custom properties (via reflection) that each behavior exposes.

Example:

List with these in the list: NPCWanderBehavior NPCMoveToBehavior NPCIdleBehaviour

The inspector shows each subclass with their properties, and modifying them seems to save those values (at least ,when I set the values on them, and I switch between nodes or run the game, those values persist). The problem is that when I save the scene, exit, and restart, those values are gone and the list only has the base class for these as serialized.

So if I have this list of commands:

NPCWanderBehavior NPCMoveToBehavior NPCIdleBehaviour

added to a game object component in the scene through my custom editor, when I save and reload my list is:

NPCCommandBase NPCCommandBase NPCCommandBase

So it looks like even though all the classes are marked serializable, that when saved only the base class is serialized, none of the subclasses.

Is there a solution to this? The custom inspector would go a LONG way to managing the command list for the level designer, and it would be quite elegant if I could get this to work.

We use the same serializer for all Unity object types (textures,materials,gameobjects,components,audioclips), as we do for script instances. While this is great in many aspects, it falls short in some others, which you have hit. The serializer does not support polymorphism. so if you make a:

`List`, and you put a dog, giraffe, and a cat in there, when that list gets serialized and deserialized, you'll end up with 3 animal objects. (assuming Animal is not abstract. if it is, you should get an error). Only fields from the animal class will be serialized during serialization, and during deserialization, the deserializer only looks at the type of the declared field `(List`) when deciding what kind of objects to put in there. It does not look at the type of objects that were serialized.

Usually I work around this by:

  • coming up with a solution where I don't need to serialize these objects
  • serialize three seperate fields: `List`, `List`, and `List`
  • put the logic of all three animals inside a single animal class, with an enum describing which animal it represents, and some if statements in class methods to select the correct behaviour based on the enum.

Additionally, as I just discovered, you can't Serialize IList, only List, which I suppose is related to the polymorphism thing.

I don’t know if it has changed since time Lucas Meijer’s answer was posted but it would seem that you CAN get serialization to support inheritance in this way, i.e. populating a List< BaseClass > with instances of DerivedClass and have the derived instances serialized properly after closing/reopening/playing/stopping, if the Base class itself extends from ScriptableObject. I learned this reading the following post on Serialization. I also made a quick example to test myself.

I saw this answer myself about a year or so ago, and it lead me to change the design of a feature I was working on. It seemed as if it would be impossible. I am now considering re factoring to make it match my original plan. I wonder if there is any reason to avoid using ScriptableObject for this purpose?

Hi, i think you should see:
http://forum.unity3d.com/threads/155352-Serialization-Best-Practices-Megapost

Look at “General Array Serialization”, seems that ScriptableObject do the job.