Odin is not initializing private, non-serialized fields on elements of my polymorphic List

Issue #633 resolved
David Rochin created an issue

What happened?

I have a SerializedScriptableObject that has a polymorphic list field. Elements on said list lose their private, non-serialized, constructor-initialized fields when you hit Play or recompile.

⚠ I’m not trying to serialize the fields. I’m trying to get them to initialize, just like you can do with Monobehaviors and ScriptableObjects fields.

How can we reproduce it?

I prepared a test project for you. All you have to do is open the ScriptableObject that is on the Assets folders and follow instructions.

If screenshots would help explain or demonstrate your issue, please include these.

After hitting Play:

This is the code of my private non-serialized fields:

What version of Unity are you using?

2019.2.9f1

What version of Odin are you using?

2.1.9

Do you have Editor Only mode enabled?

No

What operating system are you on?

Windows 10 64 bits

Comments (11)

  1. Lyrcaxis

    @David Rochin [ShowInInspectorAttribute] does not imply Odin Serializes that as well.

    Same as [OdinSerialize] doesn’t imply the member will be visible on the inspector.

    You need to apply the following attributes to the field in order for it to be both serialized and displayed: [ShowInInspector, OdinSerialize]

    I suggest you take a look at the Serialization Debugger to avoid issues like this in the future 🙂

  2. David Rochin reporter

    I’m not trying to serialize the field. I’m just trying to initialize it. You can do that with Monobehaviors and ScriptableObjects. I don’t see why Polymorphic instances should not initialize its fields aswell.

  3. Tor Esa Vestergaard

    Sorry for the long waiting time - this is expected behaviour. Odin does not invoke class constructors to create instances during deserialization, meaning that once a type is saved down, that’s it. New fields added do not have their default initialized values set upon deserialization. This is a conscious choice - it is either this set of problems, or another, more difficult set of problems. We decided we’d rather have this one. It's part of a general pattern of having less implicit magic, and more strict, explicit specifications of what exactly is going to happen and how everything works - and to keep the serializer more stable and safe to use overall.

    What you can do is initialize all of your field values in a private void method marked with the [OnDeserializing] method. That will then be invoked during deserialization after the instance is created, but before the instance is populated with deserialized data.

  4. Log in to comment