Wednesday, May 8, 2024
HomeGame Developmentunity - How to save and load animation curves recorded at runtime?

unity – How to save and load animation curves recorded at runtime?


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:

  1. Save code; go back to editor

Then, Unity:

  1. Unity-serializes everything to native
    • (The callback) Deconstruct the AnimationCurve into the for-serialization-only member (composed only of System.Serializable types)
  2. Load the new Managed assemblies
  3. Unity-deserialize from native into new Managed
    • (The callback) Reconstruct the AnimationCurve‘s data using the data in the for-serialization-only member
RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments