Unity.JsonUtility序列化指南

大致說明


Unity5引入了一套新的Json工具——JsonUtility。
總的來說就是不好用。有大量Json需求的朋友,建議出門左轉,使用其他Json庫

原本Json相對簡單,但是這套工具使用的是Unity Serializer。和我們日常使用的Json序列化有點差異。支持序列化MonoBehaviour的子類,ScriptableObject的子類以及包含[Serializable]標籤的類和結構。
這套Api主要優勢是Unity內置,在很多簡單的場景,可以方便我們開發。

基本用法


不做介紹,點擊查看官方文檔

默認爲utf-8格式,不支持utf-8帶bom
如果序列化的時候遇到莫名其妙的JSON parse error: Invalid value,可以先檢查一下是否使用了帶bom的格式。

序列化ScriptableObject和MonoBehavior


public class JsonTest : MonoBehaviour
{
    /// <summary>
    /// 序列化字段
    /// </summary>
    public int Value;

    void Start()
    {
        // 賦值Value爲2
        Value = 1;

        // {"Value":1}
        var json = JsonUtility.ToJson(this);

        // 賦值Value爲2
        Value = 2;

        // 數據被重新寫入,Value賦值爲1
        JsonUtility.FromJsonOverwrite(json, this);

        // ArgumentException: Cannot deserialize JSON to new instances of type 'JsonTest.'
        // 不支持直接反序列化生成一個MonoBehavior的子類
        var fromJson = JsonUtility.FromJson<JsonTest>(json);
    }
}

序列化List和Dictionary和Array


如果要支持List和Array,建議寫一個包裝類,將其包含再裏邊。並且泛型中加入[Serializable]標籤
如果要支持Dictionary,建議改寫成List。

// 沒有包含[Serializable]的類,不可被包含在序列化類內
public class Item1
{
    public string Str;
}

// 包含標籤可以正常序列化
[Serializable]
public class Item2
{
    public string Str;
}

public class ListCollection
{
    // 可正常序列化
    public List<int> Item0;
    // 沒有標籤不可正常序列化
    public List<Item1> Item1;
    // 有標籤可以正常序列化
    public List<Item2> Item2;
}

public void Run()
{
    var collection = new ListCollection()
    {
        Item0 = new List<int>() { 0, 1, 2, 3, 4 },
        Item1 = new List<Item1>() { new Item1() { Str = "1" }, new Item1() { Str = "2" } },
        Item2 = new List<Item2>() { new Item2() { Str = "1" }, new Item2() { Str = "2" } }
    };

    // {"Item0":[0,1,2,3,4],"Item2":[{"Str":"1"},{"Str":"2"}]}
    Debug.Log(JsonUtility.ToJson(collection));
    // {}
    Debug.Log(JsonUtility.ToJson(collection.Item0));
    // {}
    Debug.Log(JsonUtility.ToJson(collection.Item1));
    // {}
    Debug.Log(JsonUtility.ToJson(collection.Item2));

    // ArgumentException: JSON must represent an object type.
    var fromJson = JsonUtility.FromJson<List<int>>("[0,1,2,3,4]");
    Debug.Log(fromJson.Count);
}

這裏提供一個歪果仁寫的快速包裝方法。需要的朋友可以考慮使用。

// 出處
// https://forum.unity3d.com/threads/how-to-load-an-array-with-jsonutility.375735/#post-2585129
public class JsonHelper
{
    public static T[] getJsonArray<T>(string json)
    {
        string newJson = "{ \"array\": " + json + "}";
        Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>> (newJson);
        return wrapper.array;
    }

    [Serializable]
    private class Wrapper<T>
    {
        public T[] array;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章