Unity中序列化和反序列化Json和Json数组
Q:
I have a list of items send from a PHP file to unity using WWW
.
我有一个使用WWW
从 PHP 文件发送到 unity 的项目列表。
The WWW.text
looks like:WWW.text
文本如下所示:
[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]
Where I trim the extra []
from the string
. When I try to parse it using Boomlagoon.JSON
, only the first object is retrieved. I found out that I have to deserialize()
the list and have imported MiniJSON.
我从string
中删除了多余的[]
。当我尝试使用Boomlagoon.JSON
解析它时,仅检索第一个对象。我发现我必须deserialize()
列表并导入 MiniJSON。
But I am confused how to deserialize()
this list. I want to loop through every JSON object and retrieve data. How can I do this in Unity using C#?
但我很困惑如何deserialize()
这个列表。我想循环遍历每个 JSON 对象并检索数据。如何在 Unity 中使用 C# 执行此操作?
The class I am using is
我正在使用的课程是
public class player
{
public string playerId { get; set; }
public string playerLoc { get; set; }
public string playerNick { get; set; }
}
After trimming the []
I am able to parse the json using MiniJSON. But it is returning only the first KeyValuePair
.
修剪[]
后,我可以使用 MiniJSON 解析 json。但它只返回第一个KeyValuePair
。
IDictionary<string, object> players = Json.Deserialize(serviceData) as IDictionary<string, object>;
foreach (KeyValuePair<string, object> kvp in players)
{
Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
}
Thanks! 谢谢!
A:
Unity added JsonUtility to their API after 5.3.3 Update. Forget about all the 3rd party libraries unless you are doing something more complicated. JsonUtility is faster than other Json libraries. Update to Unity 5.3.3 version or above then try the solution below.
Unity 在5.3.3更新后将JsonUtility添加到其 API 中。忘记所有第三方库,除非您正在做更复杂的事情。 JsonUtility 比其他 Json 库更快。更新到 Unity 5.3.3版本或更高版本,然后尝试以下解决方案。
JsonUtility
is a lightweight API. Only simple types are supported. It does not support collections such as Dictionary. One exception is List
. It supports List
and List
array!JsonUtility
是一个轻量级 API。仅支持简单类型。它不支持字典等集合。一个例外是List
。它支持List
和List
数组!
If you need to serialize a Dictionary
or do something other than simply serializing and deserializing simple datatypes, use a third-party API. Otherwise, continue reading.
如果您需要序列化Dictionary
或执行除简单序列化和反序列化简单数据类型之外的其他操作,请使用第三方 API。否则,请继续阅读。
Example class to serialize:
要序列化的示例类:
[Serializable]
public class Player
{
public string playerId;
public string playerLoc;
public string playerNick;
}
1. ONE DATA OBJECT (NON-ARRAY JSON)
1. 一个数据对象(非数组 JSON)
Serializing Part A:
序列化 A 部分:
Serialize to Json with the public static string ToJson(object obj);
method.
使用以下命令序列化为Json public static string ToJson(object obj);
方法。
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);
Output: 输出:
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
Serializing Part B:
序列化 B 部分:
Serialize to Json with the public static string ToJson(object obj, bool prettyPrint);
method overload. Simply passing true
to the JsonUtility.ToJson
function will format the data. Compare the output below to the output above.
使用以下命令序列化为Json public static string ToJson(object obj, bool prettyPrint);
方法重载。只需将true
传递给JsonUtility.ToJson
函数即可格式化数据。将下面的输出与上面的输出进行比较。
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);
Output: 输出:
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}
Deserializing Part A:
反序列化 A 部分:
Deserialize json with the public static T FromJson(string json);
method overload.
反序列化json public static T FromJson(string json);
方法重载。
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);
Deserializing Part B:
反序列化 B 部分:
Deserialize json with the public static object FromJson(string json, Type type);
method overload.
反序列化json public static object FromJson(string json, Type type);
方法重载。
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);
Deserializing Part C:
反序列化 C 部分:
Deserialize json with the public static void FromJsonOverwrite(string json, object objectToOverwrite);
method. When JsonUtility.FromJsonOverwrite
is used, no new instance of that Object you are deserializing to will be created. It will simply re-use the instance you pass in and overwrite its values.
反序列化json public static void FromJsonOverwrite(string json, object objectToOverwrite);
方法。使用JsonUtility.FromJsonOverwrite
时,不会创建要反序列化到的该对象的新实例。它只会重新使用您传入的实例并覆盖其值。
This is efficient and should be used if possible.
这是有效的,如果可能的话应该使用。
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. MULTIPLE DATA(ARRAY JSON)
2. 多数据(JSON数组)
Your Json contains multiple data objects. For example playerId
appeared more than once. Unity’s JsonUtility
does not support array as it is still new but you can use a helper class from this person to get array working with JsonUtility
.
您的 Json 包含多个数据对象。例如playerId
出现不止一次。 Unity 的JsonUtility
不支持数组,因为它仍然是新的,但您可以使用此人提供的帮助器类来让数组与JsonUtility
一起使用。
Create a class called JsonHelper
. Copy the JsonHelper directly from below.
创建一个名为JsonHelper
的类。直接从下面复制JsonHelper。
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:
序列化 Json 数组:
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);
Output: 输出:
{
"Items": [
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
},
{
"playerId": "512343283",
"playerLoc": "User2",
"playerNick": "Rand Nick 2"
}
]
}
Deserializing Json Array:
反序列化 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);
Output: 输出:
Powai 波维
User2 用户2
If this is a Json array from the server and you did not create it by hand:
如果这是来自服务器的 Json 数组并且您没有手动创建它:
You may have to Add {"Items":
in front of the received string then add }
at the end of it.
您可能需要在收到的字符串前面添加{"Items":
然后在其末尾添加}
。
I made a simple function for this:
我为此做了一个简单的函数:
string fixJson(string value)
{
value = "{\"Items\":" + value + "}";
return value;
}
then you can use it:
然后你可以使用它:
string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);
3.Deserialize json string without class && De-serializing Json with numeric properties
3.反序列化不带类的json字符串 && 反序列化带有数字属性的Json
This is a Json that starts with a number or numeric properties.
这是一个以数字或数字属性开头的 Json。
For example: 例如:
{
"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
does not support this because the “15m” property starts with a number. A class variable cannot start with an integer.
Unity 的JsonUtility
不支持此功能,因为“15m”属性以数字开头。类变量不能以整数开头。
Download SimpleJSON.cs
from Unity’s wiki.
从 Unity 的wiki下载SimpleJSON.cs
。
To get the “15m” property of USD:
要获得 USD 的“15m”财产:
var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);
To get the “15m” property of ISK:
获取ISK的“15m”属性:
var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);
To get the “15m” property of NZD:
获取NZD的“15m”属性:
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
The rest of the Json properties that doesn’t start with a numeric digit can be handled by Unity’s JsonUtility.
其余不以数字开头的 Json 属性可以由 Unity 的 JsonUtility 处理。
4.TROUBLESHOOTING JsonUtility:
4.JsonUtility 故障排除:
Problems when serializing with JsonUtility.ToJson
?
使用JsonUtility.ToJson
序列化时出现问题?
Getting empty string or “{}
” with JsonUtility.ToJson
?
使用JsonUtility.ToJson
获取空字符串或“ {}
”?
A. Make sure that the class is not an array. If it is, use the helper class above with JsonHelper.ToJson
instead of JsonUtility.ToJson
.
A.确保该类不是数组。如果是,请将上面的帮助器类与JsonHelper.ToJson
一起使用,而不是JsonUtility.ToJson
。
B. Add [Serializable]
to the top of the class you are serializing.
B.将[Serializable]
添加到要序列化的类的顶部。
C. Remove property from the class. For example, in the variable, public string playerId { get; set; }
remove { get; set; }
. Unity cannot serialize this.
C.从类中删除属性。例如,在变量中, public string playerId { get; set; }
删除{ get; set; }
。 Unity 无法序列化它。
Problems when deserializing with JsonUtility.FromJson
?
使用JsonUtility.FromJson
反序列化时出现问题?
A. If you get Null
, make sure that the Json is not a Json array. If it is, use the helper class above with JsonHelper.FromJson
instead of JsonUtility.FromJson
.
A.如果得到Null
,请确保 Json 不是 Json 数组。如果是,请将上面的帮助器类与JsonHelper.FromJson
一起使用,而不是JsonUtility.FromJson
。
B. If you get NullReferenceException
while deserializing, add [Serializable]
to the top of the class.
B.如果反序列化时出现NullReferenceException
,请将[Serializable]
添加到类的顶部。
C.Any other problems, verify that your json is valid. Go to this site here and paste the json. It should show you if the json is valid. It should also generate the proper class with the Json. Just make sure to remove remove { get; set; }
from each variable and also add [Serializable]
to the top of each class generated.
C .如有其他问题,请验证您的 json 是否有效。转到此站点并粘贴 json。它应该显示 json 是否有效。它还应该使用 Json 生成正确的类。只要确保删除remove { get; set; }
来自每个变量,并将[Serializable]
添加到生成的每个类的顶部。
Newtonsoft.Json: 牛顿软件.Json:
If for some reason Newtonsoft.Json must be used then as of February 2022 it may now be obtained directly from Unity from here: com.unity.nuget.newtonsoft-json@3.0. Just add com.unity.nuget.newtonsoft-json
via the package manager. For details see Install official via UPM by kalle (jag).
如果由于某种原因必须使用Newtonsoft.Json ,那么从 2022 年 2 月开始,现在可以直接从 Unity 获取: com.unity.nuget.newtonsoft-json@3.0 。只需添加 com.unity.nuget.newtonsoft-json
通过包管理器。有关详细信息,请参阅通过kalle (jag)通过 UPM 安装官方版本。
You can also check out the forked version for Unity from SaladLab / Json.Net.Unity3D. Note that you may experience crash if certain feature is used. Be careful.
您还可以从SaladLab / Json.Net.Unity3D查看 Unity 的分叉版本。请注意,如果使用某些功能,您可能会遇到崩溃。当心。
To answer your question:
回答你的问题:
Your original data is 你的原始数据是
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
Add {"Items":
in front of it then add }
at the end of it.
在其前面添加{"Items":
然后在其末尾添加}
。
Code to do this: 执行此操作的代码:
serviceData = "{\"Items\":" + serviceData + "}";
Now you have: 现在你有:
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
To serialize the multiple data from php as arrays, you can now do
要将来自 php 的多个数据序列化为数组,您现在可以这样做
public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
is your first dataplayerInstance[0]
是你的第一个数据
playerInstance[1]
is your second dataplayerInstance[1]
是你的第二个数据
playerInstance[2]
is your third dataplayerInstance[2]
是你的第三个数据
or data inside the class with playerInstance[0].playerLoc
, playerInstance[1].playerLoc
, playerInstance[2].playerLoc
……
或者类内的数据为playerInstance[0].playerLoc
, playerInstance[1].playerLoc
, playerInstance[2].playerLoc
……
You can use playerInstance.Length
to check the length before accessing it.
您可以在访问之前使用playerInstance.Length
检查长度。
NOTE: Remove { get; set; }
from the player
class. If you have { get; set; }
, it won’t work. Unity’s JsonUtility
does NOT work with class members that are defined as properties.
注意:删除{ get; set; }
来自player
{ get; set; }
。如果你有{ get; set; }
,它不会工作。 Unity 的JsonUtility
不适用于定义为properties 的类成员。
本站发布的内容若无意中侵犯到您的权益,请联系我们,本站将在一个工作日内删除。如遇到任何问题请联系客服QQ:2385367137
912sy » Unity中序列化和反序列化Json和Json数组