- Home /
Custom Editor for a scriptable object with an abstract list
Hello,
I have a Scriptable Object by the name "AIStrategyBuildingBlock" with a list of objects of a class by the name "AICondition".
AICondition is an abstract class with several classes deriving from it.
What I wish to do, is to create a CustomEditor for "AIStrategyBuildingBlock" which will allow me to add and modify the AICondition's within it. Probably by having a dropdown which chooses the type of AICondition to add before clicking the "add button".
I was able to achieve this without SerializedFields but no matter what I did I couldn't get the object to keep its values after pressing "Play" (SetDirty didn't help), so I'm assuming my approach was wrong.
How would you approach solving this issue?
Are you using Undo.RecordObject in your Editor Scripts? Serialized values set by scripts usually only become persistent when you do.
I tried both " Undo.RecordObject" and "EditorUtility.SetDirty". None of them help. All the "simple" values are saved, but the list gets reset whenever I press play.
Have you tried using serializedObject.FindProperty to get the list's value in the onEnable()?
Answer by Bunny83 · Jun 21, 2021 at 07:16 AM
Note that for the longest time it was true that Unity did not support polymorphism for custom serializable classes as they were always serialized based on the field type. So there was no explicit type information stored in the serialized data which is of course necessary in order to deserialized the exact instance.
However they come up with a kinda hacky solution: the SerializeReference attribute. This will treat a reference type of a custom serializable class differently. Unity will actually create a "local" reference system within the same serialization stream.
So all the serialization system needs is that attribute on your field. However the downside is, you don't get any automatic inspector support here. Since you can now store derived classes in that field, you have to create a custom inspector / editor code to actually create and maintain those instances. This makes it almost impossible to use the normal recommended SerializedObject / SerializedProperty route- That also means providing multi object editing would become a real pain since when you select several "AIStrategyBuildingBlock" objects at once and the field / array could contain several different types, how would you handle that?
So going that route means:
you loose multi object editing because there's most likely no sensible way how to implement it.
you may have to mix the SerializedObject / SerializedProperty approach with direct accessing the target / targets reference or just use the target(s) object(s).
you have to write a lot of extra editor code in order to create and maintain those serialized references.
So in summary: It's now possible to serialize abstract type references, however it requires quite a bit of work and has some limitations.
Answer by ArseneySorokin · Jun 21, 2021 at 05:33 AM
I wasn't able to solve the problem. Turns out Unity cannot serialize abstract classes. https://docs.unity3d.com/Manual/script-Serialization.html
How to ensure a custom class can be serialized
Ensure it:
Has the Serializable attribute
Is not abstract
Is not static
Is not generic, though it may inherit from a generic class