Serializing Without SerializedMonoBehaviour


If you wish to add Odin serialization support to one of your existing UnityEngine.Object type classes, without inheriting from SerializedMonoBehaviour etc, you can easily do so. It's explained in depth in our manual here: Implementing The Odin Serializer.

However, you can also use Odin's serialization API to serialize and deserialize your data into and from a simple byte array.

Usually, you would use the SerializationUtility class, which wraps the serialization system and handles all the boilerplate code involved. Some example code might be as follows:

// Take a class with some random garbage string data, random numbers, unity objects, and cyclic references
public class MyData
{
    public string str = new string(Enumerable.Range(0, 20).Select(i => (char)UnityEngine.Random.Range(50, 150)).ToArray());
    public List<float> numbers = new List<float>(Enumerable.Range(0, 10).Select(i => UnityEngine.Random.Range(0f, 100f)));
    public GameObject unityObjectReference = UnityEngine.Object.FindObjectOfType<UnityEngine.GameObject>();
    public MyData reference;
}

// Somewhere, a method to serialize data to json might look something like this
private void SerializeData()
{
    // Save to Assets folder
    string path = Application.dataPath + "/data.json";

    // Initialize some data
    var originalData = new MyData();
    originalData.reference = new MyData();
    originalData.reference.reference = originalData;

    // Unity should be allowed to handle serialization and deserialization of its own weird objects.
    // So if your data-graph contains UnityEngine.Object types, you will need to provide Odin with
    // a list of UnityEngine.Object which it will then use as an external reference resolver.
    List<UnityEngine.Object> unityObjectReferences = new List<UnityEngine.Object>();

    //DataFormat dataFormat = DataFormat.Binary;
    DataFormat dataFormat = DataFormat.JSON;
    //DataFormat dataFormat = DataFormat.Nodes;

    // Serialization
    {
        var bytes = SerializationUtility.SerializeValue(originalData, dataFormat, out unityObjectReferences);
        File.WriteAllBytes(path, bytes);

        // If you want the json string, use UTF8 encoding
        // var jsonString = System.Text.Encoding.UTF8.GetString(bytes);
    }

    // Deserialization
    {
        var bytes = File.ReadAllBytes(path);

        // If you have a string to deserialize, get the bytes using UTF8 encoding
        // var bytes = System.Text.Encoding.UTF8.GetBytes(jsonString);

        var data = SerializationUtility.DeserializeValue<MyData>(bytes, dataFormat, unityObjectReferences);
    }
}

If you look in the resulting json file, you will see that Odin's json format keeps a bunch of metadata in special $-prepended entries. As such, this is not strictly speaking json that any other serializer could deserialize properly into a valid result, as there is this extra metadata such as type information, but these are necessary to be able to fully reconstruct the data to the specifications of Odin's serialization system.

Whether or not you should use this, depends on your exact use-case though. If you just want to save some very simple data to json, we would advise you to use Unity's own JsonUtility class - it's a lot faster than Odin's json serialization, which is comparatively slow. (Odin's binary format is very fast and highly optimized - the json, not so much. We just never took the time to do it, as it wasn't a high priority. Json is never used in Odin, by default.)

This website is brand new and built with the Odin 2.1 beta in mind. This means you might discover some features such as attribute expressions that are only available in the beta.

You can download the 2.1 beta from here and read the patch-notes here.