Saving Nested ScriptableObjects in Custom Editor

I have been making a dialog system along with a custom editor window to nicely edit it with.

Each conversation is its own scriptableobject asset that can be dropped onto an npc.
Each conversation has nodes, which are basically a snippet of text and a character portrait along with a list of responses (Yes / No etc).
And the responses link to other nodes, pretty basic setup.

The problems started when i needed polymorphism on the dialog responses to incorporate a text input field as a possible response type. As far as i know a class marked with System.Serializable wont be properly serialized with polymorphism so i made the responses derive from ScriptableObject.

Creating responses in the custom editor and adding them the system seemed to work, but when i exit and reload unity all of the responses are null!

I’ve done some research and it seems that AssetDatabase.AddObjectToAsset() might be reqired to have nested scriptable objects persist, but this means they have to be manually removed from the asset when deleted to prevent leaks.

Is there an easier way to nest a data structure in a scriptableObject asset that requires polymorphism? Or is this the only way unity provides?

Since Unity’s serializer doesn’t handle polymorphism, that is unfortunately the cleanest way.

Alternatively, you could make your conversation implement ISerializationCallbackReceiver. In OnBeforeSerialize, record two strings for each node: its type name and a JSON representation of its contents (using JsonUtility.ToJson). In OnAfterDeserialize, for each record create a node of the specified type using JsonUtility.FromJson.

Or save your conversation as a CSV file instead of using Unity’s serialization. The advantage is that you can load it in Excel or Google Sheets, run it through a spell checker, send it to translators, etc. But you have to read and write the CSV file yourself instead of implicitly relying on Unity’s serialization.