Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
We use cookies to ensure that we provide you with the best possible experience on our site.
Your essential source on Unity and web development
Your essential source on Unity and web development
JsonUtility is a class that comes with Unity, facilitating the serialization and deserialization of content based on the JSON format.
Table of contents
JSON, or JavaScript Object Notation, is a standard text-based format for representing structured data based on JavaScript object syntax. In Unity, it allows transforming text into an instance of a C# class.
{"id":1,"username":"VectorFocus"}
This is equivalent to the following instance of this C# class:
public class User
{
public int id;
public string username;
}
var user = new User()
{
id = 1,
username = "VectorFocus"
};
To serialize an object into a JSON string, you can use the JsonUtility.ToJson method.
public class User
{
public int id;
public string username;
}
var user = new User()
{
id = 1,
username = "VectorFocus"
};
// {"id":1,"username":"VectorFocus"}
string json = JsonUtility.ToJson(user);
To deserialize a JSON-formatted string into an object, you can use JsonUtility.FromJson.
string json = "{\"id\":1,\"username\":\"VectorFocus\"}";
User user = JsonUtility.FromJson<User>(json);
JsonUtility.FromJsonOverwrite allows deserialization of JSON into classes inheriting from UnityEngine.Object (Monobehaviour and ScriptableObject). It can also be used for simpler classes by passing an object as the second parameter to update, instead of creating a new object.
using UnityEngine;
public class JsonMonobehaviour : MonoBehaviour
{
public int number;
public string informations;
private void Start()
{
string json = "{\"number\":6,\"informations\":\"my data\"}";
JsonUtility.FromJsonOverwrite(json, this);
}
}
Fields can be hidden from serialization using the [NonSerialized] attribute. Private fields and getters/setters are also ignored.
using UnityEngine;
using System;
public class JsonMonobehaviour : MonoBehaviour
{
public int number;
public string informations;
// hide from JsonUtility
[NonSerialized]
public int field;
// hide from JsonUtility
private int _field2;
// hide from JsonUtility
public int Field3 { get; set; }
}
Getters and setters can be directly serialized using the [field: SerializeField]
attribute. However, the field will be assigned a non-human-friendly key (e.g., k__BackingField
).
[field: SerializeField]
public int Field3 { get; set; }
Arrays or lists can be directly defined in the structure for simple types (int, string, etc.).
public class User
{
public int id;
public string username;
public List<int> points = new List<int>();
public int[] pointsArray;
}
Custom types can be used in your structure; just assign the [System.Serializable] attribute to your Custom class or struct.
public class User
{
public int id;
public string username;
// only one group
public Group group;
// work with list and array too
public List<Group> groups = new List<Group>();
}
[System.Serializable]
public class Group
{
public string name;
}
If your JSON data becomes enormous and JsonUtility becomes slow:
It may be a good idea to run the serialization in another thread to prevent the main thread from being blocked and the game from freezing. Since Unity 2019.1.6, we can use JsonUtility in background thread.
You should not alter any object that is being used in the function while it is running
using System.Collections;
using System.Threading;
using UnityEngine;
using UnityEngine.Events;
public class JsonBackground : MonoBehaviour
{
public class User
{
public int id;
public string username;
}
private void Start()
{
string json = "{\"id\":1,\"username\":\"VectorFocus\"}";
FromJsonBackground<User>(json, (user) =>
{
// actions with user
});
}
public void FromJsonBackground<T>(string data, UnityAction<T> unityAction)
{
StartCoroutine(FromJsonBackgroundCoroutine<T>(data, unityAction));
}
private IEnumerator FromJsonBackgroundCoroutine<T>(string data, UnityAction<T> unityAction)
{
T convertData = default(T);
var thread = new Thread(() =>
{
convertData = JsonUtility.FromJson<T>(data);
});
thread.Start();
while (thread.IsAlive)
{
yield return null;
}
unityAction.Invoke(convertData);
}
}
I’m not a big fan of this code, I’m not happy about mixing thread and coroutine.
Another problem is added: if the coroutine is stopped, the thread will continue to run. I haven’t yet found a solution to this problem, as Thread.Abort is obsolete and CancellationToken doesn’t seem to meet this need.
You can use C#’s Task
and async/await
features in Unity to perform these operations in the background. Remember to call Unity-related operations on the main thread when necessary.
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
public class JsonBackgroundTask : MonoBehaviour
{
public class User
{
public int id;
public string username;
}
private void Start()
{
string json = "{\"id\":1,\"username\":\"VectorFocus\"}";
FromJsonTask<User>(json, (user) =>
{
// actions with user
});
AwaitSyntax();
}
public async void AwaitSyntax()
{
// if you prefer without callback with await
string json = "{\"id\":1,\"username\":\"VectorFocus\"}";
var user = await FromJsonGetTask<User>(json);
}
public async void FromJsonTask<T>(string json, UnityAction unityAction)
{
var data = await Task.Run(() => JsonUtility.FromJson<T>(json));
unityAction?.Invoke(data);
}
public Task FromJsonGetTask<T>(string json)
{
return Task.Run(() => JsonUtility.FromJson<T>(json));
}
}
I have the same problem here as with the code using the thread, the task will continue even if the object is destroyed.
You can modify the code to add a CancellationToken, but it doesn’t seem possible to stop JsonUtility execution once it’s started.
EditorJsonUtility is a similar utility to JsonUtility but is specifically designed for the Unity Editor. It provides more control over serialization and deserialization in editor scripts.
using UnityEditor;
using UnityEngine;
public class EditorJsonExample
{
[MenuItem("Tools/Deserialize JSON")]
private static void DeserializeJson()
{
User user = new User() { id = 1 };
string json = EditorJsonUtility.ToJson(user);
}
}
Original illustration by J S of Pixabay