我有一个使用WWW
从PHP文件发送到Unity的项目列表。
WWW.text
看起来像:
[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]
我从[]
修剪额外的string
。当我尝试使用Boomlagoon.JSON
解析它时,只检索第一个对象。我发现我必须deserialize()
列表并导入MiniJSON。
但我很困惑如何deserialize()
此列表。我想遍历每个JSON对象并检索数据。如何使用C#在Unity中执行此操作?
我正在使用的课程是
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));
}
谢谢!
答案 0 :(得分:175)
Unity在 5.3.3 更新后将JsonUtility添加到其API中。忘掉所有第三方库,除非你做的更复杂。 JsonUtility比其他Json库更快。更新到Unity 5.3.3 版本或更高版本,然后尝试以下解决方案。
JsonUtility
是一个轻量级API。仅支持简单类型。它不支持像Dictionary这样的集合。一个例外是List
。它支持List
和List
数组!
如果您需要序列化Dictionary
或执行除简单数据类型序列化和反序列化之外的其他操作,请使用第三方API。否则,继续阅读。
要序列化的示例类:
[Serializable]
public class Player
{
public string playerId;
public string playerLoc;
public string playerNick;
}
<强> 1。一个数据对象(非阵列JSON)
序列化A部分:
使用public static string ToJson(object obj);
方法将序列化为。
Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";
//Convert to Jason
string playerToJason = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJason);
输出:
{"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 Jason
string playerToJason = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJason);
输出:
{
"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 Jason
string playerToJason = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJason);
输出:
{
"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);
输出:
博万
用户2
如果这是来自服务器的Json数组,而您没有手动创建:
您可能需要在收到的字符串前添加{"Items":
,然后在其末尾添加}
。
我为此做了一个简单的功能:
string fixJson(string value)
{
value = "{\"Items\":" + value + "}";
return value;
}
然后你可以使用它:
string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);
3.在没有class&amp;&amp;的情况下反序列化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
不支持这一点,因为&#34; 15m&#34;物业以数字开头。类变量不能以整数开头。
从Unity wiki下载 SimpleJSON.cs
。
获得&#34; 15m&#34;美元的财产:
var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);
获得&#34; 15m&#34; ISK的财产:
var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);
获得&#34; 15m&#34;新西兰财产:
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
其他不以数字开头的Json属性可以由Unity的JsonUtility处理。
4.TROUBLESHOOTING JsonUtility:
使用JsonUtility.ToJson
序列化时遇到的问题?
获取空字符串或&#34; {}
&#34;与JsonUtility.ToJson
?
<强> A 即可。确保该类不是数组。如果是,请使用上面的帮助程序类JsonHelper.ToJson
而不是JsonUtility.ToJson
。
<强>乙即可。将[Serializable]
添加到要序列化的类的顶部。
<强> C 即可。从类中删除属性。例如,在变量public string playerId { get; set; }
删除 { get; set; }
中。 Unity无法将其序列化。
使用JsonUtility.FromJson
进行反序列化时遇到的问题?
<强> A 即可。如果得到Null
,请确保Json不是Json数组。如果是,请使用上面的帮助程序类JsonHelper.FromJson
而不是JsonUtility.FromJson
。
<强>乙即可。如果您在反序列化时获得NullReferenceException
,请将[Serializable]
添加到班级的顶部。
C 。还有其他问题,请验证您的json是否有效。转到此站点here并粘贴json。它应该显示json是否有效。它还应该使用Json生成适当的类。只需确保从每个变量中删除删除 { 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].playerLoc
,playerInstance[1].playerLoc
,playerInstance[2].playerLoc
......的课程内的数据
您可以在访问之前使用playerInstance.Length
检查长度。
注意:从{ get; set; }
课程中删除 player
。如果你有{ get; set; }
,那就不行了。 Unity JsonUtility
NOT 与定义为属性的类成员一起工作。
答案 1 :(得分:9)
假设你有一个像这样的JSON
[
{
"type": "qrcode",
"symbol": [
{
"seq": 0,
"data": "HelloWorld9887725216",
"error": null
}
]
}
]
要统一解析上面的JSON,你可以像这样创建JSON模型。
[System.Serializable]
public class QrCodeResult
{
public QRCodeData[] result;
}
[System.Serializable]
public class Symbol
{
public int seq;
public string data;
public string error;
}
[System.Serializable]
public class QRCodeData
{
public string type;
public Symbol[] symbol;
}
然后只需按以下方式解析......
var myObject = JsonUtility.FromJson<QrCodeResult>("{\"result\":" + jsonString.ToString() + "}");
现在您可以根据需要修改JSON / CODE。 https://docs.unity3d.com/Manual/JSONSerialization.html
答案 2 :(得分:0)
不要修剪[]
,你应该没事。 []
标识一个JSON数组,它正是您能够迭代其元素所需的数据。
答案 3 :(得分:0)
像@Maximiliangerhardt所说,MiniJson没有正确反序列化的能力。我使用了JsonFx,就像一个魅力。适用于[]
player[] p = JsonReader.Deserialize<player[]>(serviceData);
Debug.Log(p[0].playerId +" "+ p[0].playerLoc+"--"+ p[1].playerId + " " + p[1].playerLoc+"--"+ p[2].playerId + " " + p[2].playerLoc);
答案 4 :(得分:0)
要读取JSON文件,请参考以下简单示例
您的JSON文件(StreamingAssets / Player.json)
{
"Name": "MyName",
"Level": 4
}
C#脚本
public class Demo
{
public void ReadJSON()
{
string path = Application.streamingAssetsPath + "/Player.json";
string JSONString = File.ReadAllText(path);
Player player = JsonUtility.FromJson<Player>(JSONString);
Debug.Log(player.Name);
}
}
[System.Serializable]
public class Player
{
public string Name;
public int Level;
}
答案 5 :(得分:0)
您可以使用Newtonsoft.Json
只需将Newtonsoft.dll
添加到您的项目中并使用以下脚本
using System;
using Newtonsoft.Json;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
[Serializable]
public class Person
{
public string id;
public string name;
}
public Person[] person;
private void Start()
{
var myjson = JsonConvert.SerializeObject(person);
print(myjson);
}
}
另一种解决方案是使用JsonHelper
using System;
using Newtonsoft.Json;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
[Serializable]
public class Person
{
public string id;
public string name;
}
public Person[] person;
private void Start()
{
var myjson = JsonHelper.ToJson(person);
print(myjson);
}
}
答案 6 :(得分:0)
如果您正在使用Vector3,这就是我所做的
1-我创建了一个名为Player的类
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class Player
{
public Vector3[] Position;
}
2-然后我这样称呼它
if ( _ispressed == true)
{
Player playerInstance = new Player();
playerInstance.Position = newPos;
string jsonData = JsonUtility.ToJson(playerInstance);
reference.Child("Position" + Random.Range(0, 1000000)).SetRawJsonValueAsync(jsonData);
Debug.Log(jsonData);
_ispressed = false;
}
3-这就是结果
“位置”:[ {“ x”:-2.8567452430725099,“ y”:-2.4323320388793947,“ z”:0.0}]}
答案 7 :(得分:0)
Narottam Goyal有一个很好的想法,将数组包装在json对象中,然后反序列化为结构。 下面使用泛型来解决所有类型的数组,而不是每次都创建一个新类。
[System.Serializable]
private struct JsonArrayWrapper<T> {
public T wrap_result;
}
public static T ParseJsonArray<T>(string json) {
var temp = JsonUtility.FromJson<JsonArrayWrapper<T>>("{\" wrap_result\":" + json + "}");
return temp.wrap_result;
}
它可以通过以下方式使用:
string[] options = ParseJsonArray<string[]>(someArrayOfStringsJson);
在Unity 2020中,有一个官方的newtonsoft软件包,它是一个更好的json库。