Search Unity

Inheritance Vs Serialization Problem

Discussion in 'Scripting' started by PROE_, Apr 11, 2019.

  1. PROE_

    PROE_

    Joined:
    Feb 20, 2016
    Posts:
    32
    I'm making a tycoon game where I have a base class called Product and inheriting classes such as Game, GameEngine, MarketingCampaign etc. Everything is working fine until I load back serialized data... ProductManager has variable of Product type which to I assign Game, GameEngine etc. instances, but Unity serializer ignores that. Due to that even casts aren't working after loading. I get plenty of "specified cast is not valid" errors...
    So what to do with this? Should I combine inherited classes into one "megaclass" containg all variables from all types and just determine which type of product it is with enum?
    Is there another solution?

    Thanks in advance :)
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    I'm going to hazard a guess that 'Product' which all these other classes inherits from, does not fall in the UnityEngine.Object inheritance chain (as a ScriptableObject or MonoBehaviour).

    The unity serialization engine does not save the type of the object when it serializes. Instead it infers the type from the field/variable its serializing. The benefit to this is if you change the type name, it still works. The downside is if you rely on polymorphic fields/variables... it does NOT work.

    The exception to this is for unity objects. Since Unity serializes unity objects by reference, rather than by value, the type of the object is conserved (looked up via the objects guid). This is why you can have a 'Component' variable that successfully references any component (Collider, Transform, etc).

    Your options are:

    1) Declare your variables/fields that get serialized explicitly as the type the object is, and not some polymorphic parent type.

    2) Convert your types to a unity object type like ScriptableObject, but this unfortunately comes with the added necessity of creating assets for each instance in your project.

    3) The most extreme and that is to serialize it yourself into a byte array or string using the ISerializationCallbackReceiver, and then shove the result into a private serialized field for unity to pack away for you. This requires a lot of extra work on your part, clutters up the serialization process, requires a 3rd party serializer, and significantly impacts speed.

    ...

    There may be other options out there that I'm not listing... it's the morning here at work and I'm only taking a moment out of my coffee break to answer this before getting back to it.
     
    eugeneloza likes this.
  3. Unity_Ghost13

    Unity_Ghost13

    Joined:
    Jan 26, 2019
    Posts:
    8
    I don't know if this can be consider as a solution to your problem but you can work with intefaces instead a Class Hierarchy , you'll get the same result and it's even more flexible for the code. Some times it works for me.
     
  4. PROE_

    PROE_

    Joined:
    Feb 20, 2016
    Posts:
    32
    Interfaces wouldn't work in this case.

    @lordofduct Thanks for answer and explanation :) Seems like the easiest and fastest solution is to combine these classes. Maybe it's not ideal but at least I will be sure that it works properly and making 'old' classes partial with Product won't make it very unreadable.