Very weird variable behaviour

Hi!

I have been having some trouble making my code behave as it should. When I run the following code something fun happens:

It seems like the variable pEnzymes somehow contains wrong elements. The elements shown in the console are “old” elements from a prior version of the script; I made some mistakes when I first wrote the elements (for example “hexakinase,phosphogluco…” instead of “hexokinase”, “phosphoglu…”. I have “updated” the script, but the computer doesn’t get it. I have re-imported the script, restarted both Unity and Visual Code Studio and even my computer, and nothing seems to work.

Thanks for your time.

They are public arrays, thus they will be serialised. Look at the inspector of the problem component and you will see the old values serialised into it.

Serialized values should be changed via the inspector, not the inline initialisers in your code. If you don’t want it to be serialised, change the declaration so they aren’t serialized, such as making the arrays readonly if they don’t change, or decorating them with [System.NonSerialized].

This is a moment every Unity developer encounters… welcome!

Spiney is our resident Serialization SME (Subject Matter Expert), but I keep a handy cribsheet overview of this main flow:

Serialized / public fields in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

  • what the class constructor makes (either default(T) or else field initializers, eg “what’s in your code”)

  • what may be saved with the prefab

  • what may be saved with the prefab override(s)/variant(s)

  • what may be saved in the scene and not applied to the prefab

  • what may be changed in the scene and not yet saved to disk

  • what may be changed in OnEnable(), Awake(), Start(), or even later

Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

Here’s the official discussion: Serialization in Unity

If you must initialize fields, then do so in the void Reset() method, which ONLY runs in the UnityEditor.

Here’s more nitty-gritty on serialization:

Field initializers versus using Reset() function and Unity serialization:

To avoid complexity in your prefabs / scenes, I recommend NEVER using the FormerlySerializedAsAttribute

Thanks for the explanation! It somehow never stuck me that something as simple as the values in the inspector would override the code (and I have even my self overwritten other variables in the inspector !).