Search Unity

Discussion Serializing Polymorphic Data Problems

Discussion in 'Scripting' started by mopthrow, Mar 20, 2023.

  1. mopthrow

    mopthrow

    Joined:
    May 8, 2020
    Posts:
    348
    Hi, I'm having trouble with this serialization problem I wonder if anyone has any suggestions.

    The setup:

    For the first time, I'm making a save/load system for complex GameObjects. These GameObjects have interchangeable MonoBehaviours. In theory, each Mono is a container for its own data that is ready to serialize.

    The problem:

    Best illustrated with an example:

    - I have 20 different types of work zone.
    - Each work zone has a physical representation as a GameObject that for simplicity, let's say has two MonoBehaviours. One of these MonoBehaviours is common to all work zones, and the other is interchangeable depending on the type of zone.
    - When saving each type of work zone, the data from each of its MonoBehaviours are collected and placed in a SerializableWorkZoneData class, as below:

    Code (CSharp):
    1. [System.Serializable]
    2. public class SerializableWorkZoneData
    3. {
    4.     public CoreData CoreData;
    5.     public SpecialityData SpecialityData;
    6. }
    7.  
    - The CoreData is data from the work zone's MonoBehaviour that is common to all work zones. It's just size, a guid, position information. They all have it.
    - The SpecialityData is a parent class of the data that is from the work zone's Monobehaviour that vaires depending on the type of work zone it is. It's just data designed to be serialized but it could contain anything depending on what its child class is.
    - A list of these SerializableWorkZoneData are then serialized via a Json serializer.
    - There are 20 child classes inheriting from SpecialityData

    Where I get stuck:

    >> In order to serialize these 20 types of work zone, am I going to have a create a concrete 'SerializeableWorkZoneData' for every single one of the 20 child class types with a concrete SpecialityData?

    I want to just serialize the data as is as I went to the trouble of making sure my Monos are just containers for ready to serialize data, but well polymorphism serialization for Json serializers doesn't seem to be a thing. It's either unsupported (Json Utility) or isn't secure (Json.Net using TypeNameHandling to include the type data. Warning about insecurity of this approach from here: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2326).

    I really don't want to have to inflate my project by 20 classes just to serialize :| (but I will If I have to!)

    >> This is my first attempt at saving and loading complex GameObjects, and I'm finding that I spend all my time making my code neat and clean with interfaces and inheritance and the serialization is like "nope, sorry, you have do it all again, this time with simple concrete classes only".

    For those more experienced is this normal to have to wreck my nice clean polymorphic code to wedge in to a save load system? Or am I taking the wrong approach?

    Any suggestions for alternatives would be much appreciated as where I am now, it works, but it's just a lot bigger than I expected.

    Thanks
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,934
    Well your link to the MS docs includes a method of restricting types that can be deserialised. I believe you can also use a JSON converter to make it more secure as well.

    There's also the option of using less well known serialisers such as the Odin serialiser.
     
    mopthrow likes this.
  3. mopthrow

    mopthrow

    Joined:
    May 8, 2020
    Posts:
    348
    Huh you're right it does, I missed this completely, I'll give that a shot it doesn't look too complicated.

    Is this what you use? I bought Odin already for the inspector mainly but not touched the serializer. I think I'll go and learn this if it makes things easier in the long run. Do you know off hand if you have to specify the types to secure things with odin too?