Serializza e deserializza Json e Json Array in Unity

Ho una lista di elementi inviati da un file PHP all’unità usando WWW . Il WWW.text aspetto di [{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}] dove ritagliare l’extra [] dalla stringa. Quando provo ad analizzarlo usando Boomlagoon.JSON , viene recuperato solo il primo object. Ho scoperto che devo deserialize() l’elenco e ho importato MiniJSON.

Ma sono confuso su come deserializzare () questa lista. Voglio scorrere ogni object JSON e recuperare i dati. Come posso farlo in Unity usando C #?

La class che sto usando è

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

Dopo aver ritagliato il [] sono in grado di analizzare il json usando MiniJSON. Ma sta restituendo solo il primo KeyValuePair .

 IDictionary s = Json.Deserialize(serviceData) as IDictionary; foreach (KeyValuePair kvp in s) { Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value)); } 

Grazie!

Unity ha aggiunto JsonUtility alle proprie API dopo l’aggiornamento 5.3.3 . Dimentica tutte le librerie di terze parti a meno che tu non stia facendo qualcosa di più complicato. JsonUtility è più veloce di altre librerie Json. Aggiornare alla versione Unity 5.3.3 o successiva, quindi provare la soluzione seguente.

JsonUtility è un’API leggera. Sono supportati solo i tipi semplici. Non supporta raccolte come Dizionario. Un’eccezione è List . Supporta l’array List e List !

Se è necessario serializzare un Dictionary o fare qualcosa di diverso dalla semplice serializzazione e deserializzazione di semplici tipi di dati, utilizzare un’API di terze parti. Altrimenti, continua a leggere.

Esempio di class da serializzare:

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

1. UN OGGETTO DATI (NON-ARRAY JSON)

Serializzazione Parte A :

Serialize to Json con la public static string ToJson(object obj); metodo.

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

Uscita :

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

Serializzare parte B :

Serialize to Json con la public static string ToJson(object obj, bool prettyPrint); sovraccarico di metodo. È sufficiente passare true alla funzione JsonUtility.ToJson formatta i dati. Confronta l’output in basso con l’output sopra.

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

Uscita :

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

Deserializzazione parte A :

Deserializzare JSON con il public static T FromJson(string json); sovraccarico di metodo.

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

Deserializzazione parte B :

Deserializzare JSON con l’ public static object FromJson(string json, Type type); sovraccarico di metodo.

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

Deserializzazione parte C :

Deserializzare json con il public static void FromJsonOverwrite(string json, object objectToOverwrite); metodo. Quando viene utilizzato JsonUtility.FromJsonOverwrite , non verrà creata alcuna nuova istanza dell’object che si sta deserializzando. Semplicemente riutilizzerà l’istanza che hai passato e sovrascriverà i suoi valori.

Questo è efficiente e dovrebbe essere usato se ansible.

 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. DATI MULTIPLI (ARRAY JSON)

Il tuo Json contiene più oggetti di dati. Ad esempio playerId apparso più di una volta . Unity’s JsonUtility non supporta l’array in quanto è ancora nuovo, ma puoi usare una class helper da questa persona per far funzionare array con JsonUtility .

Crea una class chiamata JsonHelper . Copia il JsonHelper direttamente dal basso.

 public static class JsonHelper { public static T[] FromJson(string json) { Wrapper wrapper = JsonUtility.FromJson>(json); return wrapper.Items; } public static string ToJson(T[] array) { Wrapper wrapper = new Wrapper(); wrapper.Items = array; return JsonUtility.ToJson(wrapper); } public static string ToJson(T[] array, bool prettyPrint) { Wrapper wrapper = new Wrapper(); wrapper.Items = array; return JsonUtility.ToJson(wrapper, prettyPrint); } [Serializable] private class Wrapper { public T[] Items; } } 

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

Uscita :

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

Deserializing 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(jsonString); Debug.Log(player[0].playerLoc); Debug.Log(player[1].playerLoc); 

Uscita :

Powai

Utente2


Se questo è un array Json dal server e non lo hai creato a mano :

Potrebbe essere necessario aggiungere {"Items": davanti alla stringa ricevuta, quindi aggiungere } alla fine di esso.

Ho fatto una semplice funzione per questo:

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

allora puoi usarlo:

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

3.Deserialize json string senza class && De-serializing Json con proprietà numeriche

Questo è un Json che inizia con un numero o proprietà numeriche.

Per esempio:

 { "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’s JsonUtility non supporta questo perché la proprietà “15m” inizia con un numero. Una variabile di class non può iniziare con un numero intero.

Scarica SimpleJSON.cs dal wiki di Unity.

Per ottenere la proprietà “15m” di USD:

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

Per ottenere la proprietà “15m” dell’ISK:

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

Per ottenere la proprietà “15m” di NZD:

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

Il resto delle proprietà Json che non iniziano con una cifra numerica può essere gestito da Unity’s JsonUtility.


4. RISOLUZIONE DEI PROBLEMI JsonUtility:

Problemi durante la serializzazione con JsonUtility.ToJson ?

Ottenere una stringa vuota o ” {} ” con JsonUtility.ToJson ?

A. Assicurati che la class non sia un array. In tal caso, utilizzare la class helper in alto con JsonHelper.ToJson anziché JsonUtility.ToJson .

B. Aggiungi [Serializable] all’inizio della class che stai serializzando.

C. Rimuovi proprietà dalla class. Ad esempio, nella variabile, public string playerId { get; set; } public string playerId { get; set; } public string playerId { get; set; } remove { get; set; } { get; set; } { get; set; } . Unity non può serializzare questo.

Problemi durante la deserializzazione con JsonUtility.FromJson ?

A. Se ottieni Null , assicurati che Json non sia un array Json. Se lo è, usa la class helper in alto con JsonHelper.FromJson invece di JsonUtility.FromJson .

B. Se ottieni NullReferenceException durante la deserializzazione, aggiungi [Serializable] all’inizio della class.

C. Altri problemi, verifica che il tuo json sia valido. Vai a questo sito qui e incolla il json. Dovrebbe mostrarti se il json è valido. Dovrebbe anche generare la class corretta con Json. Assicurati di rimuovere remove { get; set; } { get; set; } { get; set; } da ogni variabile e aggiungere anche [Serializable] all’inizio di ogni class generata.


Newtonsoft.Json:

Se per qualche motivo Newtonsoft.Json deve essere utilizzato, controlla qui la versione biforcuta per Unity. Notare che si può verificare un arresto anomalo se si utilizza una determinata funzionalità. Stai attento.


Per rispondere alla tua domanda :

I tuoi dati originali sono

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

Aggiungi {"Items": davanti ad esso quindi aggiungi } alla fine di esso.

Codice per fare questo:

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

Ora hai:

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

Per serializzare i dati multipli da php come array , ora puoi farlo

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

playerInstance[0] è il tuo primo dato

playerInstance[1] è il tuo secondo dato

playerInstance[2] è il tuo terzo dato

o dati all’interno della class con playerInstance[0].playerLoc , playerInstance[1].playerLoc , playerInstance[2].playerLoc ……

È ansible utilizzare playerInstance.Length per controllare la lunghezza prima di accedervi.

NOTA: rimuovere { get; set; } { get; set; } { get; set; } dalla class del player . Se hai { get; set; } { get; set; } { get; set; } , non funzionerà. JsonUtility di Unity NON funziona con i membri della class definiti come proprietà .

Supponi di avere un JSON come questo

 [ { "type": "qrcode", "symbol": [ { "seq": 0, "data": "HelloWorld9887725216", "error": null } ] } ] 

Per analizzare il JSON precedente in unità, è ansible creare un modello JSON come questo.

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

E poi semplicemente analizzare nel modo seguente …

 var myObject = JsonUtility.FromJson("{\"result\":" + jsonString.ToString() + "}"); 

Ora puoi modificare JSON / CODE in base alle tue necessità. https://docs.unity3d.com/Manual/JSONSerialization.html

devi aggiungere [System.Serializable] alla class PlayerItem , in questo modo:

 using System; [System.Serializable] public class PlayerItem { public string playerId; public string playerLoc; public string playerNick; } 

Non tagliare [] e dovresti stare bene. [] identifica un array JSON che è esattamente quello che ti serve per poter iterare i suoi elementi.

Come ha detto @Maximiliangerhardt, MiniJson non ha la capacità di deserializzare correttamente. Ho usato JsonFx e funziona come un fascino. Funziona con []

 player[] p = JsonReader.Deserialize(serviceData); Debug.Log(p[0].playerId +" "+ p[0].playerLoc+"--"+ p[1].playerId + " " + p[1].playerLoc+"--"+ p[2].playerId + " " + p[2].playerLoc);