c# - leer - Serializar y deserializar Json y Json Array en Unity
unity json array (6)
Tengo una lista de elementos enviados desde un archivo PHP a unity usando
WWW
.
El
WWW.text
parece a:
[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]
Donde recorto el extra
[]
de la
string
.
Cuando intento analizarlo usando
Boomlagoon.JSON
, solo se recupera el primer objeto.
Descubrí que tengo que
deserialize()
la lista y he importado MiniJSON.
Pero estoy confundido sobre cómo
deserialize()
esta lista.
Quiero recorrer cada objeto JSON y recuperar datos.
¿Cómo puedo hacer esto en Unity usando C #?
La clase que estoy usando es
public class player
{
public string playerId { get; set; }
public string playerLoc { get; set; }
public string playerNick { get; set; }
}
Después de recortar
[]
puedo analizar el json usando MiniJSON.
Pero solo devuelve el primer
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));
}
¡Gracias!
Como dijo @Maximiliangerhardt, MiniJson no tiene la capacidad de deserializarse correctamente.
Usé JsonFx y funciona de maravilla.
Trabaja con el
[]
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);
No recorte el
[]
y debería estar bien.
[]
identifica una matriz JSON que es exactamente lo que necesitas para poder iterar sus elementos.
Para leer el archivo JSON, consulte este sencillo ejemplo
Su archivo JSON (StreamingAssets / Player.json)
{
"Name": "MyName",
"Level": 4
}
C # Script
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;
}
Supongamos que tienes un JSON como este
[
{
"type": "qrcode",
"symbol": [
{
"seq": 0,
"data": "HelloWorld9887725216",
"error": null
}
]
}
]
Para analizar el JSON anterior en la unidad, puede crear un modelo JSON como este.
[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;
}
Y luego simplemente analizar de la siguiente manera ...
var myObject = JsonUtility.FromJson<QrCodeResult>("{/"result/":" + jsonString.ToString() + "}");
Ahora puede modificar el JSON / CODE según su necesidad. https://docs.unity3d.com/Manual/JSONSerialization.html
Unity agregó JsonUtility a su API después de la actualización 5.3.3 . Olvídate de todas las bibliotecas de terceros a menos que estés haciendo algo más complicado. JsonUtility es más rápido que otras bibliotecas Json. Actualice a la versión Unity 5.3.3 o superior y luego pruebe la solución a continuación.
JsonUtility
es una API ligera.
Solo se admiten tipos simples.
No es compatible con colecciones como Diccionario.
Una excepción es la
List
.
¡Es compatible con
List
y
List
array!
Si necesita serializar un
Dictionary
o hacer algo más que simplemente serializar y deserializar tipos de datos simples, use una API de terceros.
De lo contrario, continúa leyendo.
Clase de ejemplo para serializar:
[Serializable]
public class Player
{
public string playerId;
public string playerLoc;
public string playerNick;
}
1. UN OBJETO DE DATOS (JSON NO ARRAY)
Serializando la Parte A :
Serializar
a Json con la
public static string ToJson(object obj);
método.
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);
Salida :
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
Serializando la Parte B :
Serialice a Json con la
public static string ToJson(object obj, bool prettyPrint);
método de sobrecarga.
Simplemente pasando
true
a la función
JsonUtility.ToJson
formateará los datos.
Compare la salida de abajo con la salida de arriba.
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);
Salida :
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}
Deserialización de la Parte A :
Deserializar
json con el
public static T FromJson(string json);
método de sobrecarga.
string jsonString = "{/"playerId/":/"8484239823/",/"playerLoc/":/"Powai/",/"playerNick/":/"Random Nick/"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);
Deserialización de la Parte B :
Deserializar
json con el
public static object FromJson(string json, Type type);
método de sobrecarga.
string jsonString = "{/"playerId/":/"8484239823/",/"playerLoc/":/"Powai/",/"playerNick/":/"Random Nick/"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);
Deserialización de la Parte C :
Deserializar
json con el
public static void FromJsonOverwrite(string json, object objectToOverwrite);
método.
Cuando se utiliza
JsonUtility.FromJsonOverwrite
, no se
JsonUtility.FromJsonOverwrite
ninguna nueva instancia de ese Objeto que está deserializando.
Simplemente reutilizará la instancia que pase y sobrescribirá sus valores.
Esto es eficiente y debe usarse si es posible.
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. DATOS MÚLTIPLES (ARRAY JSON)
Su Json contiene múltiples objetos de datos.
Por ejemplo,
playerId
apareció más de
una vez
.
JsonUtility
de Unity no admite la matriz, ya que aún es nueva, pero puede usar una clase
helper
de esta persona para que la
matriz
funcione con
JsonUtility
.
Crea una clase llamada
JsonHelper
.
Copie el JsonHelper directamente desde abajo.
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;
}
}
Serializando 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 Jason
string playerToJason = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJason);
Salida :
{
"Items": [
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
},
{
"playerId": "512343283",
"playerLoc": "User2",
"playerNick": "Rand Nick 2"
}
]
}
Deserialización de la matriz de 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);
Salida :
Powai
Usuario2
Si se trata de una matriz Json del servidor y no la creó a mano :
Puede que tenga que agregar
{"Items":
delante de la cadena recibida y luego agregar
}
al final.
Hice una función simple para esto:
string fixJson(string value)
{
value = "{/"Items/":" + value + "}";
return value;
}
entonces puedes usarlo:
string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);
3.Deserializar la cadena json sin clase && Des serializar Json con propiedades numéricas
Este es un Json que comienza con un número o propiedades numéricas.
Por ejemplo:
{
"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" : "$"}
}
JsonUtility
de Unity no admite esto porque la propiedad "15m" comienza con un número.
Una variable de clase no puede comenzar con un número entero.
Descargue
SimpleJSON.cs
del
wiki
de Unity.
Para obtener la propiedad "USD 15m":
var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);
Para obtener la propiedad "15m" de ISK:
var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);
Para obtener la propiedad "15m" de NZD:
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
El resto de las propiedades de Json que no comienzan con un dígito numérico pueden ser manejadas por JsonUtility de Unity.
4. SOLUCIÓN DE PROBLEMAS JsonUtility:
¿Problemas al serializar con
JsonUtility.ToJson
?
¿Obtener una cadena vacía o "
{}
" con
JsonUtility.ToJson
?
A.
Asegúrese de que la clase no sea una matriz.
Si es así, use la clase de ayuda anterior con
JsonHelper.ToJson
lugar de
JsonUtility.ToJson
.
B.
Agregue
[Serializable]
a la parte superior de la clase que está serializando.
C.
Eliminar propiedad de la clase.
Por ejemplo, en la variable,
public string playerId { get; set; }
public string playerId { get; set; }
public string playerId { get; set; }
eliminar
{ get; set; }
{ get; set; }
{ get; set; }
.
La unidad no puede serializar esto.
¿Problemas al deserializar con
JsonUtility.FromJson
?
A.
Si obtiene
Null
, asegúrese de que Json no sea una matriz Json.
Si es así, use la clase de ayuda anterior con
JsonHelper.FromJson
lugar de
JsonUtility.FromJson
.
B.
Si obtiene
NullReferenceException
mientras deserializa, agregue
[Serializable]
al principio de la clase.
C.
Cualquier otro problema, verifique que su json sea válido.
Vaya a este sitio
here
y pegue el json.
Debería mostrarte si el json es válido.
También debería generar la clase adecuada con el Json.
Solo asegúrese de eliminar
remove
{ get; set; }
{ get; set; }
{ get; set; }
de cada variable y también agregue
[Serializable]
a la parte superior de cada clase generada.
Newtonsoft.Json:
Si por alguna razón se debe utilizar Newtonsoft.Json , consulte la versión bifurcada de Unity here . Tenga en cuenta que puede experimentar un bloqueo si se utiliza cierta función. Ten cuidado.
Para responder a su pregunta :
Sus datos originales son
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
Agregue
{"Items":
delante
de él y luego
agregue
}
al
final
.
Código para hacer esto:
serviceData = "{/"Items/":" + serviceData + "}";
Ahora tu tienes:
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
Para serializar los datos múltiples de php como matrices , ahora puede hacer
public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
es tu primer dato
playerInstance[1]
es su segundo dato
playerInstance[2]
es su tercer dato
o datos dentro de la clase con
playerInstance[0].playerLoc
,
playerInstance[1].playerLoc
,
playerInstance[2].playerLoc
......
Puede usar
playerInstance.Length
para verificar la longitud antes de acceder a ella.
NOTA:
Eliminar
{ get; set; }
{ get; set; }
{ get; set; }
de la clase de
player
.
Si tienes
{ get; set; }
{ get; set; }
{ get; set; }
, no funcionará.
JsonUtility
de Unity
NO
funciona con miembros de la clase que se definen como
propiedades
.
tienes que agregar
[System.Serializable]
a la clase
PlayerItem
, así:
using System;
[System.Serializable]
public class PlayerItem {
public string playerId;
public string playerLoc;
public string playerNick;
}