Unity đã thêm JsonUtility vào API của họ sau Bản cập nhật 5.3.3 . Quên tất cả các thư viện của bên thứ 3 trừ khi bạn đang làm điều gì đó phức tạp hơn. JsonUtility nhanh hơn các thư viện Json khác. Cập nhật lên phiên bản Unity 5.3.3 trở lên rồi thử giải pháp bên dưới.
JsonUtility
là một API nhẹ. Chỉ những loại đơn giản mới được hỗ trợ. Nó không hỗ trợ các bộ sưu tập như Từ điển. Một ngoại lệ là List
. Nó hỗ trợ List
và List
mảng!
Nếu bạn cần tuần tự hóa một Dictionary
hoặc làm điều gì đó khác ngoài việc tuần tự hóa và giải mã hóa các kiểu dữ liệu đơn giản, hãy sử dụng API của bên thứ ba. Nếu không, hãy tiếp tục đọc.
Lớp mẫu để tuần tự hóa:
[Serializable]
public class Player
{
public string playerId;
public string playerLoc;
public string playerNick;
}
1. MỘT ĐỐI TƯỢNG DỮ LIỆU (JSON KHÔNG ĐẾN)
Serializing Part A :
Nối tiếp đến Json với public static string ToJson(object obj);
phương thức.
Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";
//Convert to JSON
string playerToJson = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJson);
Đầu ra :
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
Serializing Part B :
Nối tiếp thành Json với public static string ToJson(object obj, bool prettyPrint);
phương thức quá tải. Chỉ cần chuyển true
đến JsonUtility.ToJson
hàm sẽ định dạng dữ liệu. So sánh đầu ra bên dưới với đầu ra ở trên.
Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";
//Convert to JSON
string playerToJson = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJson);
Đầu ra :
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}
Hủy số hóa Phần A :
Hủy phiên bản json với public static T FromJson(string json);
phương thức quá tải.
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);
Hủy số hóa Phần B :
Hủy phiên bản json với public static object FromJson(string json, Type type);
phương thức quá tải.
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);
Hủy số hóa Phần C :
Hủy phiên bản json bằng public static void FromJsonOverwrite(string json, object objectToOverwrite);
phương thức này. Khi JsonUtility.FromJsonOverwrite
được sử dụng, sẽ không có phiên bản mới nào của Đối tượng mà bạn đang giải mã hóa sẽ được tạo. Nó sẽ chỉ đơn giản là sử dụng lại cá thể bạn chuyển vào và ghi đè lên các giá trị của nó.
Điều này là hiệu quả và nên được sử dụng nếu có thể.
Player playerInstance;
void Start()
{
//Must create instance once
playerInstance = new Player();
deserialize();
}
void deserialize()
{
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
//Overwrite the values in the existing class instance "playerInstance". Less memory Allocation
JsonUtility.FromJsonOverwrite(jsonString, playerInstance);
Debug.Log(playerInstance.playerLoc);
}
2. NHIỀU DỮ LIỆU (ARRAY JSON)
Json của bạn chứa nhiều đối tượng dữ liệu. Ví dụ playerId
xuất hiện nhiều hơn một lần . Unity's JsonUtility
không hỗ trợ mảng vì nó vẫn còn mới nhưng bạn có thể sử dụng lớp trợ giúp từ người này để làm việc với mảngJsonUtility
.
Tạo một lớp được gọi là JsonHelper
. Sao chép JsonHelper trực tiếp từ bên dưới.
public static class JsonHelper
{
public static T[] FromJson<T>(string json)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return wrapper.Items;
}
public static string ToJson<T>(T[] array)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper);
}
public static string ToJson<T>(T[] array, bool prettyPrint)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper, prettyPrint);
}
[Serializable]
private class Wrapper<T>
{
public T[] Items;
}
}
Serializing Json Array :
Player[] playerInstance = new Player[2];
playerInstance[0] = new Player();
playerInstance[0].playerId = "8484239823";
playerInstance[0].playerLoc = "Powai";
playerInstance[0].playerNick = "Random Nick";
playerInstance[1] = new Player();
playerInstance[1].playerId = "512343283";
playerInstance[1].playerLoc = "User2";
playerInstance[1].playerNick = "Rand Nick 2";
//Convert to JSON
string playerToJson = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJson);
Đầu ra :
{
"Items": [
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
},
{
"playerId": "512343283",
"playerLoc": "User2",
"playerNick": "Rand Nick 2"
}
]
}
Hủy số hóa mảng Json :
string jsonString = "{\r\n \"Items\": [\r\n {\r\n \"playerId\": \"8484239823\",\r\n \"playerLoc\": \"Powai\",\r\n \"playerNick\": \"Random Nick\"\r\n },\r\n {\r\n \"playerId\": \"512343283\",\r\n \"playerLoc\": \"User2\",\r\n \"playerNick\": \"Rand Nick 2\"\r\n }\r\n ]\r\n}";
Player[] player = JsonHelper.FromJson<Player>(jsonString);
Debug.Log(player[0].playerLoc);
Debug.Log(player[1].playerLoc);
Đầu ra :
Powai
Người dùng2
Nếu đây là một mảng Json từ máy chủ và bạn không tạo nó bằng tay :
Bạn có thể phải Thêm {"Items":
vào trước chuỗi nhận được sau đó thêm }
vào cuối chuỗi đó.
Tôi đã tạo một hàm đơn giản cho điều này:
string fixJson(string value)
{
value = "{\"Items\":" + value + "}";
return value;
}
thì bạn có thể sử dụng nó:
string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);
3. Giải mã hóa chuỗi json không có lớp && Hủy tuần tự hóa Json với các thuộc tính số
Đây là một Json bắt đầu bằng một số hoặc thuộc tính số.
Ví dụ:
{
"USD" : {"15m" : 1740.01, "last" : 1740.01, "buy" : 1740.01, "sell" : 1744.74, "symbol" : "$"},
"ISK" : {"15m" : 179479.11, "last" : 179479.11, "buy" : 179479.11, "sell" : 179967, "symbol" : "kr"},
"NZD" : {"15m" : 2522.84, "last" : 2522.84, "buy" : 2522.84, "sell" : 2529.69, "symbol" : "$"}
}
Unity's JsonUtility
không hỗ trợ điều này vì thuộc tính "15m" bắt đầu bằng một số. Một biến lớp không thể bắt đầu bằng một số nguyên.
Tải xuống SimpleJSON.cs
từ wiki của Unity .
Để có được tài sản "15 triệu" USD:
var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);
Để nhận thuộc tính "15m" của ISK:
var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);
Để có được thuộc tính "15m" của NZD:
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
Phần còn lại của các thuộc tính Json không bắt đầu bằng chữ số có thể được xử lý bởi Unity's JsonUtility.
4. KHẮC PHỤC SỰ CỐ JsonUtility:
Các vấn đề khi nối tiếp với JsonUtility.ToJson
?
Nhận chuỗi rỗng hoặc " {}
" với JsonUtility.ToJson
?
Một . Đảm bảo rằng lớp không phải là một mảng. Nếu có, hãy sử dụng lớp trợ giúp ở trên với JsonHelper.ToJson
thay vì JsonUtility.ToJson
.
B . Thêm [Serializable]
vào đầu lớp mà bạn đang tuần tự hóa.
C . Xóa tài sản khỏi lớp. Ví dụ, trong biến, public string playerId { get; set; }
loại bỏ { get; set; }
. Unity không thể tuần tự hóa điều này.
Các vấn đề khi deserializing với JsonUtility.FromJson
?
Một . Nếu bạn nhận được Null
, hãy đảm bảo rằng Json không phải là một mảng Json. Nếu có, hãy sử dụng lớp trợ giúp ở trên với JsonHelper.FromJson
thay vì JsonUtility.FromJson
.
B . Nếu bạn nhận được NullReferenceException
trong khi giải kích thước, hãy thêm [Serializable]
vào đầu lớp.
C .Bất kỳ vấn đề nào khác, hãy xác minh rằng json của bạn là hợp lệ. Truy cập trang web này ở đây và dán json. Nó sẽ hiển thị cho bạn nếu json hợp lệ. Nó cũng sẽ tạo ra lớp thích hợp với Json. Chỉ cần đảm bảo loại bỏ loại bỏ { get; set; }
khỏi mỗi biến và cũng thêm [Serializable]
vào đầu mỗi lớp được tạo.
Newtonsoft.Json:
Nếu vì lý do nào đó mà Newtonsoft.Json phải được sử dụng thì hãy xem phiên bản chia nhánh cho Unity tại đây . Lưu ý rằng bạn có thể gặp sự cố nếu sử dụng một số tính năng nhất định. Hãy cẩn thận.
Để trả lời câu hỏi của bạn :
Dữ liệu ban đầu của bạn là
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
Thêm {"Items":
vào trước nó rồi thêm }
vào cuối nó.
Mã để làm điều này:
serviceData = "{\"Items\":" + serviceData + "}";
Bây giờ bạn có:
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
Để serialize các nhiều dữ liệu từ php như mảng , bây giờ bạn có thể làm
public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
là dữ liệu đầu tiên của bạn
playerInstance[1]
là dữ liệu thứ hai của bạn
playerInstance[2]
là dữ liệu thứ ba của bạn
hoặc dữ liệu bên trong các lớp học với playerInstance[0].playerLoc
, playerInstance[1].playerLoc
, playerInstance[2].playerLoc
......
Bạn có thể sử dụng playerInstance.Length
để kiểm tra độ dài trước khi truy cập nó.
LƯU Ý: Xóa { get; set; }
khỏi player
lớp học. Nếu bạn có { get; set; }
, nó sẽ không hoạt động. Unity của JsonUtility
không KHÔNG làm việc với các thành viên lớp được xác định là thuộc tính .
[
và]
? Đó là những gì làm cho nó một danh sách. Chỉ cần dừng việc xóa nó và giải mã hóa nó thành một mảng hoặc một danh sách và tôi hy vọng nó sẽ ổn. Vui lòng đăng mã mà bạn đã thử.