If you go to the definition of AnimationCurve
(F12 in VS), you’ll see that it is not marked [System.Serializable]
and no amount of coaxing will change that.
When you change your code and go back to the editor, everything that was there is Unity.Serialized()
(don’t look for it; not a real thing) to native, the new managed code is loaded, and then the old values are Unity.Deserialized()
back into the new data structure blindly. If you rename something, for example, the editor won’t know to put the old data in the new place so, instead, it just throws away the old-data and creates new, new-data.
Your only recourse is to provide the methods needed to System.De/Serialize
the non-serializable curves. You can do so by iterating each KeyFrame
in the curve and manually exporting the data somewhere, some way. You’ll also need to provide the method that converts that raw data back into an AnimationCurve
that appears to be the same one as before.
ScriptableObject
is not meant for persistent storage of run-time-generated data. They allow you to create design-time “assets” out of chunks of data that scripts can reference, rather than contain/copy. You are free to create new ScriptableObjects
at run-time and you are able to permanently store them in the asset database. However (big but), this depends on the Editor
namespace which doesn’t exist in builds. If you use them just to help design the game, you’re still required to provide the implementation to make them System.Serializable
(they are also only Unity.Serializable
). In case you consider doing so, you cannot simply add [System.Serializable]
to a ScriptableObject
because the base class (UnityEngine.Object
) still won’t be [System.Serializable]
.
Instead, the object that contains the curves can implement the ISerializationCallbackReceiver interface and use the corresponding methods to extract the KeyFrames
into a serializable form. You can make a new SerializableKeyFrame
class that contains the same names and types as the real KeyFrame
class except they’ll be stored as members, not as properties. The SerializableKeyFrame
class will need to be marked [System.Serializable]
to be eligible for serialization. As well, the for-serialization-only member within the curve-containing object (presumably a List<SerializableKeyFrame>
will need to be public or marked [SerializeField]
. You can leave it public and hide it with [HideInInspector]
. You are free to use a struct
instead of a class
but are subject to the normal drawbacks (no default values for members) which may not really affect you.
Overview:
You:
- Save code; go back to editor
Then, Unity:
- Unity-serializes everything to native
- (The callback) Deconstruct the
AnimationCurve
into the for-serialization-only member (composed only ofSystem.Serializable
types)
- (The callback) Deconstruct the
- Load the new Managed assemblies
- Unity-deserialize from native into new Managed
- (The callback) Reconstruct the
AnimationCurve
‘s data using the data in the for-serialization-only member
- (The callback) Reconstruct the