gpt4 book ai didi

c# - 在Unity中序列化和反序列化Json和Json数组

转载 作者:太空宇宙 更新时间:2023-11-03 14:56:18 25 4
gpt4 key购买 nike

我有使用WWW从PHP文件发送到统一文件的项目列表。

WWW.text看起来像:

[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]


我在哪里修剪 []中多余的 string。当我尝试使用 Boomlagoon.JSON解析它时,仅检索第一个对象。我发现我必须 deserialize()该列表并导入了MiniJSON。

但是我很困惑如何 deserialize()这个列表。我想遍历每个JSON对象并检索数据。如何在Unity中使用C#做到这一点?

我正在使用的课程是

public class player
{
public string playerId { get; set; }
public string playerLoc { get; set; }
public string playerNick { get; set; }
}


修剪 []后,我可以使用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));
}


谢谢!

最佳答案

5.3.3更新后,Unity将JsonUtility添加到其API。除非您正在做更复杂的事情,否则请忘掉所有第三方库。 JsonUtility比其他Json库快。更新到Unity 5.3.3版本或更高版本,然后尝试以下解决方案。

JsonUtility是轻量级的API。仅支持简单类型。它不支持字典等集合。 List是一个例外。它支持ListList数组!

如果您需要序列化Dictionary或执行其他操作而不是简单地序列化和反序列化简单数据类型,请使用第三方API。否则,请继续阅读。

要序列化的示例类:

[Serializable]
public class Player
{
public string playerId;
public string playerLoc;
public string playerNick;
}


1.一个数据对象(非数组JSON)

序列化A部分:

使用 public static string ToJson(object obj);方法序列化为Json。

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);


输出:

{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}




序列化B部分:

使用 public static string ToJson(object obj, bool prettyPrint);方法重载序列化到Json。只需将 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);


输出:

{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}




反序列化A部分:

使用 public static T FromJson(string json);方法重载反序列化json。

string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);


B部分反序列化:

使用 public static object FromJson(string json, Type type);方法重载反序列化json。

string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);




反序列化C部分:

使用 public static void FromJsonOverwrite(string json, object objectToOverwrite);方法反序列化json。使用 JsonUtility.FromJsonOverwrite时,不会创建要反序列化的该对象的新实例。它只会重复使用您传入的实例并覆盖其值。

这是有效的,应尽可能使用。

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.多重数据(ARRAY JSON)

您的Json包含多个数据对象。例如, playerId出现了不止一次。 Unity的 JsonUtility不支持数组,因为它仍然是新的,但是您可以使用此人的 helper类来使数组与 JsonUtility一起使用。

创建一个名为 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;
}
}


序列化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);


输出:

{
"Items": [
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
},
{
"playerId": "512343283",
"playerLoc": "User2",
"playerNick": "Rand Nick 2"
}
]
}




反序列化Json Array:

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);


输出:


  宝威
  
  用户2




如果这是来自服务器的Json数组,而您没有手动创建它:

您可能必须在收到的字符串之前添加 {"Items":,然后在其末尾添加 }

我为此做了一个简单的功能:

string fixJson(string value)
{
value = "{\"Items\":" + value + "}";
return value;
}


那么您可以使用它:

string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);




3.不使用类对json字符串反序列化&&用数字属性反序列化Json

这是一个以数字或数字属性开头的Json。

例如:

{ 
"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的 JsonUtility不支持此功能,因为“ 15m”属性以数字开头。类变量不能以整数开头。

从Unity的 wiki下载 SimpleJSON.cs

要获得USD的“ 15m”属性:

var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);


要获得ISK的“ 15m”属性:

var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);


要获得NZD的“ 15m”属性:

var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);


其余以数字开头的Json属性可以由Unity的JsonUtility处理。



4.麻烦的JsonUtility:

使用 JsonUtility.ToJson序列化时出现问题?

使用 {}获取空字符串或“ JsonUtility.ToJson”?

答:确保该类不是数组。如果是这样,请将上面的帮助程序类与 JsonHelper.ToJson而不是 JsonUtility.ToJson一起使用。

B.在要序列化的类的顶部添加 [Serializable]

C.从类中删除属性。例如,在变量中, public string playerId { get; set; }删除 { get; set; }。 Unity无法序列化它。

使用 JsonUtility.FromJson反序列化时出现问题吗?

答:如果得到 Null,请确保Json不是Json数组。如果是这样,请将上面的帮助程序类与 JsonHelper.FromJson而不是 JsonUtility.FromJson一起使用。

B.如果反序列化时出现 NullReferenceException,则将 [Serializable]添加到类的顶部。

C.其他任何问题,请确认您的json有效。转到此站点 here并粘贴json。它应该显示json是否有效。它还应该使用Json生成适当的类。只需确保从每个变量中删除remove { get; set; },并将 [Serializable]添加到所生成的每个类的顶部即可。



Newtonsoft.Json:

如果由于某种原因必须使用Newtonsoft.Json,请检查Unity here的分叉版本。请注意,如果使用某些功能,则可能会崩溃。小心。



要回答您的问题:

您的原始数据是

 [{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]


在其前面添加 {"Items":,然后在其末尾添加 }

代码来做到这一点:

serviceData = "{\"Items\":" + serviceData + "}";


现在您有了:

 {"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}


要将来自php的多个数据序列化为数组,您现在可以执行

public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);


playerInstance[0]是您的第一个数据

playerInstance[1]是您的第二个数据

playerInstance[2]是您的第三个数据

或类中带有 playerInstance[0].playerLocplayerInstance[1].playerLocplayerInstance[2].playerLoc的数据...

您可以使用 playerInstance.Length在访问之前检查长度。

注意:从 { get; set; }类中删除 player。如果您有 { get; set; },它将不起作用。 Unity的 JsonUtility不适用于定义为属性的类成员。

关于c# - 在Unity中序列化和反序列化Json和Json数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48864136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com