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
{
    /// 
    /// 序列化字段
    /// 
    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(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;
    // 有标签可以正常序列化
    public List Item2;
}

public void Run()
{
    var collection = new ListCollection()
    {
        Item0 = new List<int>() { 0, 1, 2, 3, 4 },
        Item1 = new List() { new Item1() { Str = "1" }, new Item1() { Str = "2" } },
        Item2 = new List() { 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.FromJsonint>>("[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(string json)
    {
        string newJson = "{ \"array\": " + json + "}";
        Wrapper wrapper = JsonUtility.FromJson> (newJson);
        return wrapper.array;
    }

    [Serializable]
    private class Wrapper
    {
        public T[] array;
    }
}

你可能感兴趣的:(Unity)