JSON Serialization API

JSON Serialization API

New in 5.3 is an API for converting objects to and from JSON format.

To serialize an object to JSON format, use JsonUtility.ToJson:

string json = JsonUtility.ToJson(myObject)

To convert from JSON back into a newly-created object, use JsonUtility.FromJson:

MyObject myObject = JsonUtility.FromJson<MyObject>(json);

It’s also possible to take JSON data and deserialize it ‘into’ an already-created object, overwriting data that is already present:

JsonUtility.FromJsonOverwrite(json, myObject);

Together, these allow you to write a class like:

[Serializable]

public class MyObject

{

public int level;

public float timeElapsed;

public string playerName;

}

and quickly convert it to/from:

{“level”:1,”timeElapsed”:47.5,”playerName”:”Dr Charles Francis”}

Which platforms are supported?

From 5.3.0a3 onwards, all platforms are supported.

Which types are supported?

The API supports any MonoBehaviour-subclass, ScriptableObject-subclass, or plain class/struct with the [Serializable] attribute. The object you pass in is fed to the standard Unity serializer for processing, so the same rules and limitations apply as they do in the Inspector: only fields are serialized, and types like Dictionary<> are not supported.

FromJson() does not support MonoBehaviour-derived types because it has no way to know which GameObject the result should be attached to. To deserialize a MonoBehaviour you must use AddComponent() to create it and then use FromJsonOverwrite() to load data into it. This restriction does not exist for ScriptableObject-derived types.

Passing other types directly to the API – e.g. primitive types or arrays – is not currently supported, though this support may be added in a coming update. For now it’s necessary to wrap such types in a class or struct of some sort.

Also, in the Editor only, it is possible to pass any UnityEngine.Object-derived type to ToJson(). This will produce JSON that contains the same data as the YAML representation of the object. This JSON can also be written back to objects using FromJsonOverwrite().

What is performance like?

Benchmark tests have shown JsonUtility to be anywhere between 5x and 40x faster than popular .NET JSON solutions (albeit with fewer features than some of them).

GC Memory usage is at a minimum:

  • ToJson() allocates GC memory only for the returned string.

  • FromJson() allocates GC memory only for the returned object, as well as any subobjects needed (e.g. strings and classes).

  • FromJsonOverwrite() allocates GC memory only as necessary for written fields (e.g. strings and classes). If all fields being overwritten by the JSON are value-typed, it should not allocate any GC memory.

What control do I have over the output of ToJson()?

ToJson supports pretty-printing the JSON output. It is off by default but you can turn it on by passing true as the second parameter.

Fields can be omitted from the output by using the [NonSerialized] attribute.

We are exploring possibilities for greater control over the output on a field-by-field level – particularly controlling the field name used on the JSON side, and the format of things like enums. There is no support for this right now.

How do I use FromJson() if I don’t know the type ahead of time?

Deserialize the JSON into a class or struct that contains ‘common’ fields, and then use the values of those fields to work out what actual type you want. Then deserialize a second time into that type.

We are exploring possibilities for a more efficient type-hinting system which would avoid the need for parsing the JSON twice. There is no support for this right now.

What’s planned / in the pipe for future updates?

In no particular order, here are some of the ideas under consideration/research:

  • FromJsonAsync

  • Support for loading direct from .json TextAsset files in the project + in AssetBundles

  • Support for loading direct from external .json files

  • Support for loading direct from WWW / WebRequest

  • Per-field control over the field’s JSON name

  • Support for serializing enums as strings

  • Root type selection based on a JSON key

Leave a Comment

Your email address will not be published. Required fields are marked *