小编典典

在Unity中序列化和反序列化Json和Json数组

c#

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

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

谢谢!


阅读 295

收藏
2020-05-19

共1个答案

小编典典

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

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

如果您需要序列化a 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.多重数据(ARRAY JSON)

您的Json包含多个数据对象。例如playerId出现了 不止一次 。Unity
JsonUtility尚不支持数组,因为它仍然是新的,但您可以使用此人的帮助程序类使 数组 与一起工作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 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);

输出

{
    "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”属性以数字开头。类变量不能以整数开头。

SimpleJSON.cs
从Unity的wiki下载。

要获得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

。添加[Serializable]到您要序列化的类的顶部。

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

反序列化时出现问题JsonUtility.FromJson


。如果得到Null,请确保Json不是Json数组。如果是,使用辅助类以上JsonHelper.FromJson的代替JsonUtility.FromJson

。如果NullReferenceException在反序列化时遇到问题,请添加[Serializable]到该类的顶部。

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


Newtonsoft.Json:

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


要回答您的问题

您的原始数据是

 [{"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在访问之前检查长度。

注意: 从课程中 删除* 。如果您有,它将无法正常工作。Unity的确实 与被定义为类成员的工作 性质{ get; set; }``player``{ get; set; }``JsonUtility ***

2020-05-19