gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 12:43:18 25 4
gpt4 key购买 nike

我有一个使用 WWW 从 PHP 文件发送到 unity 的项目列表.
WWW.text看起来像:

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

我修剪多余的地方 []来自 string .当我尝试使用 Boomlagoon.JSON 解析它时,只检索第一个对象。我发现我必须 deserialize()列表并已导入 MiniJSON。

但我很困惑如何 deserialize()这份 list 。我想遍历每个 JSON 对象并检索数据。如何使用 C# 在 Unity 中执行此操作?

我正在使用的类(class)是
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));
}

谢谢!

最佳答案

统一添加 JsonUtility到他们的 API 之后5.3.3 更新。除非您正在做一些更复杂的事情,否则请忘记所有 3rd 方库。 JsonUtility 比其他 Json 库更快。更新到 Unity 5.3.3 版本或更高版本然后尝试下面的解决方案。
JsonUtility是一个轻量级的 API。仅支持简单类型。确实如此 不是 支持字典等集合。一个异常(exception)是 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方法重载。简单路过 trueJsonUtility.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.多数据(数组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 数组 :
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);

输出:

Powai

User2



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

您可能需要添加 {"Items":在接收到的字符串前面添加 }在它的最后。

我为此做了一个简单的函数:
string fixJson(string value)
{
value = "{\"Items\":" + value + "}";
return value;
}

然后你可以使用它:
string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);

3.Deserialize json string without class && De-serializing Json with numeric properties

这是一个以数字或数字属性开头的 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”属性以数字开头。类变量不能以整数开头。

下载 SimpleJSON.cs来自 Unity 的 wiki .

要获得美元的“1500 万”属性:
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);

要获得新西兰元的“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 .

.添加 [Serializable]到您正在序列化的类的顶部。

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

使用 JsonUtility.FromJson 反序列化时的问题?

一个 .如果您收到 Null ,确保 Json 不是 Json 数组。如果是,请使用上面的辅助类 JsonHelper.FromJson而不是 JsonUtility.FromJson .

.如果您收到 NullReferenceException反序列化时,添加 [Serializable]到类(class)的顶端。

C . 任何其他问题,请验证您的 json 是否有效。进入本站 here并粘贴json。它应该告诉你 json 是否有效。它还应该使用 Json 生成正确的类。只要确保删除 删除 { get; set; }从每个变量中添加 [Serializable]到每个类的顶部生成。

Newtonsoft.Json:

如果出于某种原因 Newtonsoft.Json 必须使用,然后查看 Unity 的 fork 版本 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].playerLoc , playerInstance[1].playerLoc , playerInstance[2].playerLoc ......

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

注意: 删除 { get; set; }来自 player类。如果您有 { get; set; } ,它不会工作。 Unity的 JsonUtility 不是 使用定义为 的类成员属性(property) .

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

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