大致说明
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;
}
}