Data Serialization in Unity (JSON friendly)

As programming is all about what you are doing with data, I thought that it would be a good idea to speak about data serialization in Unity. Especially that now we can turn data objects into JSON with JsonUtility! ❤️

What is so special about that?

Data serialization is essential for games for a variety of reasons. Saving and loading player progress or saves, sending and receiving data from a server, and in general converting data to and from a text or files. ?

For me, the best way to handle all of that is to convert objects into and from JSON. And as Unity introduced JsonUtility class, it’s even more convenient nowadays.

Of course, this class has its limitations that you have to be aware of.
It can handle only simple types (like numbers, text or arrays/lists) and serializable classes so as long as you stick with those, you will be fine! ?
You can find more information about that in Unity’s documentation available here. ?

Implementation

So as we know limitations of JsonUtility, let’s try to implement example data class and how to serialize data from and to it!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// This class is just an example of Data Model that you can create.
/// It will be converted from and to JSON thanks to JsonUtility class.
/// </summary>
[System.Serializable]
public class DataExample
{
    [System.Serializable]
    public class ArrayItemData
    {
        public string someMoreTest;
    }

    public float someFloat;
    public int someInt;

    public string someText;

    // We can even serialize other data objects inside data objects!
    public List<ArrayItemData> array;
}

You can notice that I had to put [System.Serializable] over the class name. This is required to enable serialization of objects created from that class.

Example

So now it’s just a matter of JsonUtility usage which is as easy as it can get!

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

/// <summary>
/// This class contains example of handling data serialization and deserialization using JsonUtility class.
/// You can find here saving and loading from PlayerPrefs and Files.
/// </summary>
public class DataSerializationExample : MonoBehaviour
{
    /// <summary>
    /// Unity method called in first frame.
    /// </summary>
    void Start()
    {
        // Creating object with some data.
        var data = new DataExample()
        {
            someInt = Random.Range(0, 10),
            someFloat = Random.Range(0.0f, 10.0f),
            someText = "String value example",
            array = new List<DataExample.ArrayItemData>() { new DataExample.ArrayItemData() { someMoreTest = "More text in array" }, new DataExample.ArrayItemData() { someMoreTest = "And one more" } }
        };

        // Serializing data object to Json - string.
        var serialized = JsonUtility.ToJson(data);

        // Showing serialized data in console.
        Debug.LogFormat("Data serialized to:\n{0}", serialized);

        // Deserialization of string into data object again.
        var deserialized = JsonUtility.FromJson<DataExample>(serialized);
    }
}

So you can see that it works in both ways! And when we run the code, we will get this in our console.

From this point, you can use PlayerPrefs or File to save it or load it!

    #region [Player Prefs]

    /// <summary>
    /// Method that saves json in PlayerPrefs under provided key.
    /// </summary>
    /// <param name="key">Key for PlayerPrefs.</param>
    /// <param name="json">Data in Json format.</param>
    public void SaveDataToPlayerPrefs(string key, string json)
    {
        PlayerPrefs.SetString(key, json);
    }

    /// <summary>
    /// Method that loads json from PlayerPrefs from provided key. 
    /// </summary>
    /// <returns>Data in Json format.</returns>
    /// <param name="key">Key for PlayerPrefs.</param>
    public string LoadDataFromPlayerPrefs(string key)
    {
        if (PlayerPrefs.HasKey(key))
        {
            return PlayerPrefs.GetString(key);
        }

        Debug.LogErrorFormat("There is no data in PlayerPrefs under key: {0}", key);
        return "";
    }

    #endregion

    #region [IO]

    /// <summary>
    /// Method that saves json in File under provided path.
    /// </summary>
    /// <param name="path">Path to file.</param>
    /// <param name="json">Data in Json format.</param>
    public void SaveDataToFile(string path, string json)
    {
        var filePath = Path.Combine(Application.persistentDataPath, path);

        File.WriteAllText(path, json);
    }

    /// <summary>
    /// Method that loads json from File under provided path. 
    /// </summary>
    /// <returns>Data in Json format.</returns>
    /// <param name="path">Path to file.</param>
    public string LoadDataFromFile(string path)
    {
        var filePath = Path.Combine(Application.persistentDataPath, path);
        if (File.Exists(filePath))
        {
            return File.ReadAllText(filePath);
        }

        Debug.LogErrorFormat("There is no file under path: {0}", filePath);
        return "";
    }

    #endregion

And that’s it! You just learned another useful skill in game development! ?

The whole project is available on in repository here, so you can take a look on that.

Also, If you want, in the previous post about Singleton Design Pattern I’ve created DataStorage example which would be great for storing data objects while a game is running! ?

Again, I hope you enjoyed it and if you know someone that it might be helpful for them, don’t hesitate to share it with them! ❤️

See you next time!

3 2 votes
Article Rating
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Tomasz Rembiasz
Tomasz Rembiasz
4 years ago

Kawał naprawdę dobrej i bardzo potrzebnej roboty. Szkoda, że nie po „naszemu”. Dzięki!!!

1
0
Would love your thoughts, please comment.x
()
x