0
\$\begingroup\$

I have a ScriptableObject that's already used extensively in my project:

public class SFXClip : ScriptableObject
{
    public AudioClip clip;

    // other properties
}

I want to extend it to a derived version something like this:

public class SFXRandom : SFXClip
{
    [SerializeField] List<AudioClip> audioClips;

    override public AudioClip clip
    {
        get
        {
            return audioClips[Random.Range(0, audioClips.Count)];
        }
    }
}

But of course, I can't do that without making the clip field on the original object into a virtual property. If I do that, I'll lose all the AudioClip references in existing SFXClip instances in my project's Assets.

Is there a way I can implement this change without losing that data?

\$\endgroup\$
0
2
\$\begingroup\$

Here's a cool trick you can use:

using UnityEngine.Serialization;

public class SFXClip : ScriptableObject
{
    [SerializeField, FormerlySerializedAs("clip")]
    private AudioClip _clip;

    public virtual AudioClip clip { 
        get { return _clip; } 
        set { _clip = value; } 
    }

    // other properties
}

The FormerlySerializedAs attribute from the UnityEngine.Serializaton namespace allows you to migrate saved parameters from an old name to a new one.

When the serializer doesn't find a member named _clip in the saved asset, it will look for one with its old name, clip. If it finds one, it will use that value for the new field.

When you next open and save your asset, it will be saved under the new name. So this way, you can migrate this field to be a property you can override, with no data loss.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.