Using an abstract class in the inspector

So, I’ve got a set of ‘attacks’, which are scriptable objects. I want to define an attack as a set of actions, where each action derives from the abstract class ‘Action’. For example, there would be a ‘WaitAction’ and a ‘DamageInRegionAction’, all which would extend Action. What I want is for an easy way to set this all up in the editor. I’m perfectly capable of creating the code for such a system, but I don’t know how to edit this data in the editor. I’d rather not use scriptable objects to create the action system, simply to avoid having 10 files per attack. My attack would contain an array of actions that would be performed. How would I make it so that I can specify in the editor which type of Action I want, since I won’t be using ScriptableObjects? I’ve tried using custom PropertyDrawers and enums with little avail, so any help would be appreciated. Am I just condemned to using Scriptable Objects, or is there a better solution?

1 Like

You simply can’t since Unity’s serializer does not support inheritance for custom serializable classes. Only MonoBehaviours or ScriptableObjects do support inheritance since they are the only extendable classes which represent a serializable reference type. Since you don’t want to use them it’s not possible through Unity’s serialization system. Anything else would require some nasty custom serialization workarounds.

What’s the exact problem you have with ScriptableObjects? Keep in mind that you can actually store multiple instances in a single asset file. Though this can get a bit messy. It’s far more convenient to store a single asset as a single file.

Now you have the ability to use [SerializeReference]. You can have a list of interface IAttack, and customize it in the editor like you wish. You need to write some editor code to get the ability to enter the fields of the subclasses. See: GitHub - mackysoft/Unity-SerializeReferenceExtensions: Provide popup to specify the type of the field serialized by the [SerializeReference] attribute in the inspector.

Note, an implementation of the interface does not need to be a monobehavior, it can be a class tagged with [Serializable]