1 前言
主要记录下Unity中解析json文件的方式,那么话不多说,开始吧!
2 JsonUtility
Unity官方提供的json解析方法。用起来还好,但是解析成的对象必须是提前由我们定义好的类对象,且不能解析二维数组。
2.1 语句
T是自定义对象。
T t = JsonUtility.FromJson<T>("json字符串"); //将json解析为T对象
string jsonContent = JsonUtility.ToJson(t); //将T对象解析为json
2.2 案例代码
using System.Collections.Generic;
using System;
using UnityEngine;
public class N_003_Json : MonoBehaviour
{
//json字符串
private string jsonText;
//预先创建的对象
private JsonTestData jtd;
private void Awake()
{
//初始化字符串
jsonText = "{\"data\":[{\"name\":\"可露儿\",\"age\":22},{\"name\":\"塔塔露\",\"age\":21}],\"success\":true}";
//初始化对象
jtd = new JsonTestData();
JsonTestData_Data d1 = new JsonTestData_Data();
d1.name = "光呆";
d1.Age = 1;
JsonTestData_Data d2 = new JsonTestData_Data();
d2.name = "雅喵";
d2.Age = 1;
List<JsonTestData_Data> list = new List<JsonTestData_Data>();
list.Add(d1);
list.Add(d2);
jtd.data = list;
jtd.success = true;
}
//绘制UI
private void OnGUI()
{
//绘制按钮,使用JsonUtility将Json字符串转为对象
if (GUI.Button(new Rect(120, 10, 150, 20), "JsonUtility To Object"))
{
//将json字符串转换为特定对象
JsonTestData jd = JsonUtility.FromJson<JsonTestData>(jsonText);
//打印输出
Debug.Log("转换为对象!");
Debug.Log("数据请求是否成功:" + jd.success);
Debug.Log("姓名:" + jd.data[0].name + ",年龄:" + jd.data[0].Age);
Debug.Log("姓名:" + jd.data[1].name + ",年龄:" + jd.data[1].Age);
}
//绘制按钮,使用JsonUtility将对象转为Json字符串
if (GUI.Button(new Rect(120, 50, 150, 20), "JsonUtility To Json"))
{
//将对象转为json字符串
string jsonContent = JsonUtility.ToJson(jtd);
//打印输出
Debug.Log("转换为字符串!");
Debug.Log(jsonContent);
}
}
}
//自定义的类对象
[Serializable] //涉及到序列化的类,需要加上此标签
public class JsonTestData
{
public List<JsonTestData_Data> data;
public bool success;
}
[Serializable]
public class JsonTestData_Data
{
public string name;
[SerializeField] //类中对象想要参与序列化,要么是public,要么是加上此标签
private int age;
public int Age { get { return age; } set { age = value; } }
}
2.3 案例演示
前面就说了,解析成的对象必须是我们自定义的类对象,而且也不能解析二维数组,即对象内若包含了二维数组对象(嵌套list),就会出错。基于以上的问题,有的时候JsonUtility是并不能满足需求的,所以还有另外一个解析方法:JsonConvert。
3 JsonConvert
可解析成通用对象,可解析二维数组。
3.1 安装包
需要在Unity PackageManager中把包给安装了才能使用JsonConvert。如图:
安装完成后,在代码文件中引入如下命名空间:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
3.2 语句
设对象为object。
object ob = JsonConvert.DeserializeObject<object>("json字符串"); //将json解析为T对象
string jsonContent = JsonConvert.SerializeObject(ob); //将T对象解析为json
这里需要特别说下object。JsonConvert与JsonUtility不同,它所提供的对象类型是很自由的,这里的object类型可以是:
- JObject对象(来自Newtonsoft.Json.Linq;)
- 自定义类对象
- JArray对象(来自Newtonsoft.Json.Linq;)(数组)(可多维)
- 数组(可多维)
- 集合(可多维)
- 字典
- ·······
以上只是我所知道的,特别讲下JObject、JArray。多说无益,直接看案例代码吧,通俗易懂好吧 !
3.3 案例代码
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class N_003_Json : MonoBehaviour
{
//json字符串
private string jsonText;
//预先创建的对象
private JObject jtd;
private void Awake()
{
//初始化字符串
jsonText = "{\"data\":[{\"name\":\"可露儿\",\"age\":22},{\"name\":\"塔塔露\",\"age\":21}],\"success\":true}";
//创建一个JObject对象,并初始化内容
jtd = new JObject();
JObject d1 = new JObject();
d1["name"] = "光呆";
d1["age"] = 1;
JObject d2 = new JObject();
d2["name"] = "雅喵";
d2["age"] = 1;
JArray list = new JArray();
list.Add(d1);
list.Add(d2);
jtd["data"] = list;
jtd["success"] = true;
}
//绘制UI
private void OnGUI()
{
//绘制按钮,使用JsonUtility将Json字符串转为对象
if (GUI.Button(new Rect(120, 10, 150, 20), "JsonConvert To JObject"))
{
//将json字符串转换为特定对象
JObject jd = JsonConvert.DeserializeObject<JObject>(jsonText);
//打印输出
Debug.Log("转换为对象!");
Debug.Log("数据请求是否成功:" + jd["success"]);
Debug.Log("姓名:" + jd["data"][0]["name"] + ",年龄:" + jd["data"][0]["age"]);
Debug.Log("姓名:" + jd["data"][1]["name"] + ",年龄:" + jd["data"][1]["age"]);
}
//绘制按钮,使用JsonUtility将对象转为Json字符串
if (GUI.Button(new Rect(120, 50, 150, 20), "JsonConvert To Json"))
{
//将对象转为json字符串
string jsonContent = JsonConvert.SerializeObject(jtd);
//打印输出
Debug.Log("转换为字符串!");
Debug.Log(jsonContent);
}
}
}
代码中使用了JObject和JArray,用这两个就不用自定义类对象了,相对来说方便一些。另外这两个是默认组合的,比如将一个json字符串转为了JObject后,若里面有数组,那么我们就把这个数组当作JArray类型即可。
3.4 案例演示
4 LitJSON
这是一个Unity插件。也不用非要使用自定义类型,有个类似JObject的类型,然后不能解析二维数组。当时测试发现不能解析二维数组我就直接不用了,所以这里也不多介绍,感兴趣可以自己在网上搜搜相关内容。
5 结束语
暂时先这些吧,我觉得JsonUtility、JsonConvert已经足够使用了,但用哪个还有些犹豫。个人是更倾向于使用官方提供的,毕竟是官方的,现在可能不好用,但以后可能会做对应的更新之类的,总之现在是两个都在用。