Use the JSON serilization for ScriptableObject with asset fields in Editor and Build

We trivially work around this as follows:

  • we recognize that ScriptableObjects cannot be serialized.

  • we put ALL ScriptableObjects of a given type in a single directory to enforce name uniqueness

  • we make a Repository object to retrieve these ScriptableObjects by name

  • we modify our serializable structures so they:
    ----> don’t serialize the SO itself
    ----> they serialize the name of the SO
    ----> they load the SO as a reference and look it up

You cannot use Unity’s “lite” JSON implementation to do this.

The following example uses Newtonsoft JSON, available via the Unity Package Mangler:

    [System.Serializable]
    public class MySerializableThingamajig
    {
        // this is what we drag into the inspector
        [Newtonsoft.Json.JsonIgnore]
        public VisualizationSO Visualization;

        // being a property, this doesn't appear in the inspector
        // being a proper JSON mechanism, NewtonSoft handles it correctly
        public string VizualizationName
        {
            get
            {
                return Visualization.name;
            }
            set
            {
                Visualization = VisualizationSORepository.Load(value);
            }
        }
    }

This also has the side benefit of using an easy-to-reason-about name in the save data, something you can look up directly in the project rather than some GUID or instance ID or other ambiguous number.

The big obvious hole here is if that name is serialized, the underlying ScriptableObject that the name references can:

  • change
  • become deleted
  • become invalid

But since we control the repository of these objects, we can:

  • simply elect to invalidate old names, or
  • provide lookup service to legacy names, or
  • otherwise have appropriate graceful behavior take place when stale data is deserialized.

A serialization data format specifier can be useful here, such as a version number.