我好生气,Python,JS里面一两行代码能够搞定的Json读取,在Unity中使用C#读取Json文件超多坑,爬出来一个又来一个。
主要是JsonUtility.FromJson太不给力了。
最好的方式是,使用 https://github.com/jilleJr/Newtonsoft.Json-for-Unity 这个第三方库。详情见下。
[System.Serializable]
public class CustomerInfo
{
public string application_id;
public string assigned_staff;
public float arrive_time;
public float starting_process_time;
public float finish_time;
}
[System.Serializable]
public class CustomerInfoList
{
public List<CustomerInfo> customerApplications = new List<CustomerInfo>();
}
这里是第一个坑,[System.Serializable] 必不可少,否则无法JsonUtility无法解析。见文档说明:
Internally, this method uses the Unity serializer; therefore the type you are creating must be supported by the serializer. It must be a plain class/struct marked with the Serializable attribute. Fields of the object must have types supported by the serializer. Fields that have unsupported types, as well as private fields or fields marked with the NonSerialized attribute, will be ignored.
TextAsset jsonFile = Resources.Load<TextAsset>("my_file"); // 不需要.json 后缀
string jsonString = jsonFile.text
jsonString 案例:
“[ { “application_id”: “app_1”, “assigned_staff”: “staff_1”, “arrive_time”: 1, “starting_process_time”: 3, “finish_time”: 5 }, { “application_id”: “app_2”, “assigned_staff”: “staff_2”, “arrive_time”: 2, “starting_process_time”: 4, “finish_time”: 6 } ]”
一个是使用Unity 提供的 JsonUtility.FromJson。 这里超多坑,不知道照着教程写的代码为什么会有类似于not serialzable的报错
在Step 2中,定义一个Container,
[System.Serializable]
public class CustomerInfoList
{
public List customerApplications = new List();
}
读取时,需要在上面的jsonString外面套一层“皮”,把Array变成Object
CustomerInfoList customerList = JsonUtility.FromJson(“{“customerApplications” :” +jsonString + “}”);
List customerApplication = customerList.customerApplications;
在上面代码中,“{“customerApplications” :” 就是为了在jsonString套一层皮。其实 CustomerInfoList 这个类,也是在List()套了一层皮,所以CustomerInfoList里面是customerApplications,JsonUtility.FromJson 里面写的也是customerApplications.
一个是使用第三方的库,例如Json.Net, 但是安装包好麻烦呀。
[System.Serializable]
public class StaffWithAssignedApplications
{
public string staff_id;
public List<List<string>> assigned_application_list_at_each_interval;
public Vector3 position;
}
[System.Serializable]
public class StaffContainer
{
public List<StaffWithAssignedApplications> staffs;
}
// 使用Networking.Json进行解析
using Newtonsoft.Json;
TextAsset jsonFile = Resources.Load<TextAsset>(fileName);
StaffContainer staffContainer = JsonConvert.DeserializeObject<StaffContainer>("{\"staffs\":" + jsonFile.text + "}");
using System.Collections.Generic;
using System.Text.RegularExpressions;
public static List<T> ParseJsonArray<T>(string json)
{
var regex = new Regex(@"\{(.+?)\}");
var matches = regex.Matches(json);
var list = new List<T>();
foreach (Match match in matches)
{
var itemJson = "{" + match.Groups[1].Value + "}";
var item = JsonUtility.FromJson<T>(itemJson);
list.Add(item);
}
return list;
}
// 调用:
List<CustomerInfo> finalResults = ParseJsonArray<CustomerInfo>(jsonString);
未完待续
{"key":value}
如果是
[{"key":value},{"key":value},...]
这种形式,则读取的时候需要在外面套层皮:
{
"outkey": [{"key":value},{"key":value},...]
}