This has nothing to do with “code” but with the serialized data. If you attach a script to a gameobject or simply edit a ScriptableObject inside the editor, the values of public fields are serialized in that asset.
If you now “silently” switch out the underlying classes things can go horrible wrong. In the case of enums it’s usually not that bad since it’s just an integer value. When an enum get serialized you actually serialize the corresponding int value. The “names” of the enum values are usually irrelevant for the serialized data. That usually means when you “remove” an enum item in between when they don’t have an explicitly assigned value, after deserialization you just get the wrong element. If they have an explicitly assigned value you of course get an error since the value isn’t defined in your enum.
What’s the point of working in a single project which consists of serialized data and switch out the code base?
If you ask “where” the values are serialized, the answer is: It depends:
- Objects in the scene are serilaized into the scene asset.
- The values of Scripts on prefabs are serialized into the prefab asset
- And of course the values of ScriptableObject assets are serialized into those asset files.
- (edit) I forget to mention that there’s also the hot-reload feature. Which means all currently loaded instances of serializable classes inside the editor get temporarily serialized before an assembly reload and those instances are recreated and deserialized after the reload. This serialized data isn’t “stored” anywhere on disk but is only hold to be able to recreate all currently open windows / object / scenes on the fly.
You can go to Edit → ProjectSettings → Editor and set the “Asset Serialization” mode to “Force Text”. That way you can open any asset file in a normal text editor. Unity uses YAML as text serialization format. There you will find your serialized value(s).
Just to be clear. An enum like this:
public enum Test {A, B, D, E}
Would have the values A = 0, B = 1, D = 2 and E = 3 while an enum like this
public enum Test {A, B, C, D, E}
would have the values A = 0, B = 1, C = 2, D = 3, E = 4
That means if you serialize an enum variable which is set to “C” you actually store the value “2”. If you deserialize the object with the types exchanged the “C” would become a “D”.
However you can define an enum like this:
public enum Test {
A = 0,
B = 1,
D = 42,
E = 5,
}
In which case the value “2” doesn’t exist at all so you might get an error when an enum field tries to display the value. Note: Any enum can take any integer value. Example:
public Test myVar;
myVar = (Test)356;
This does work just fine as myVar is essentially just an integer value. However the value it represents doesn’t have an “assigned symbol” so when you try to find the name for that value it will fail.