Sérialiser et désérialiser le tableau JSON et JSON dans Unity

J'ai une liste d'éléments envoyés d'un fichier PHP à unity en utilisant WWW. Le WWW.text ressemble à [{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}] où je coupe le [] supplémentaire de la chaîne. Lorsque j'essaie de l'analyser en utilisant Boomlagoon.JSON, seul le premier objet est récupéré. J'ai découvert que je devais deserialize() la liste et avoir importé MiniJSON.

Mais je suis confus comment désérialiser () cette liste. Je veux parcourir chaque objet JSON et récupérer des données. Comment puis-je le faire dans Unity en utilisant C#?

La classe que j'utilise est

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

Après avoir coupé le [] je suis capable d'analyser le json en utilisant MiniJSON. Mais il ne retourne que le premier KeyValuePair.

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

Merci!

47
demandé sur Luzan Baral 2016-03-26 22:13:21

5 réponses

Unity a ajouté JsonUtility à leur API après 5.3.3 mise à jour. Oubliez toutes les bibliothèques 3ème partie, sauf si vous faites quelque chose de plus compliqué. JsonUtility est plus rapide que les autres bibliothèques Json. Mise à jour vers Unity 5.3.3 version ou ci-dessus, puis essayez la solution ci-dessous.

JsonUtility est une API légère. Seuls les types simples sont pris en charge. Il nepas supporte des collections telles que Dictionary. Une exception est List. Il prend en charge List et List tableau!

Si vous devez sérialiser un Dictionary ou faire autre chose que simplement sérialiser et désérialiser des types de données simples, utilisez une API tierce. Sinon, continuer la lecture.

Exemple de classe à sérialiser:

[Serializable]
public class Player
{

    public string playerId;
    public string playerLoc;
    public string playerNick;
}

1. UN OBJET DE DONNÉES (JSON NON-ARRAY)

Sérialisation De La Partie A :

Sérialiser Json avec la public static string ToJson(object obj); méthode.

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

Sortie:

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

Sérialisation De La Partie B :

Sérialiser Json avec la public static string ToJson(object obj, bool prettyPrint); surcharge de la méthode. Le simple fait de passer true à la fonction JsonUtility.ToJson formatera les données. Comparez la sortie ci-dessous à la sortie ci-dessus.

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

Sortie:

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

Désérialisation De La Partie A :

Désérialiser json avec le public static T FromJson(string json); méthode surcharge.

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

Désérialisation De La Partie B :

Désérialiser json avec le public static object FromJson(string json, Type type); surcharge de la méthode.

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

Désérialisation De La Partie C :

Désérialiser json avec le public static void FromJsonOverwrite(string json, object objectToOverwrite); la méthode. Lorsque JsonUtility.FromJsonOverwrite est utilisé, aucune nouvelle instance de cet objet que vous désérialisez ne sera créée. Il réutilisera simplement l'instance que vous transmettez et écrasera ses valeurs.

C'est efficace et devrait être utilisé si possible.

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. PLUSIEURS DONNÉES (TABLEAU JSON)

Votre Json contient plusieurs objets de données. Par exemple playerId est apparu plus de une fois. L'unité de JsonUtility ne prend pas en charge tableau comme il est encore nouveau, mais vous pouvez utiliser un helper classe de cette personne pour obtenir matrice travailler avec JsonUtility.

Créez une classe appelée JsonHelper. Copiez le JsonHelper directement à partir du bas.

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

Sérialisation De Json Tableau :

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

Sortie:

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

Désérialisation Du Tableau 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);

Sortie:

Powai

Utilisateur2


Si c'est un tableau Json du serveur et que vous ne l'avez pas créé à la main :

Vous devrez peut-être ajouter {"Items": devant la chaîne reçue, puis Ajouter } à la fin de celle-ci.

J'ai fait une fonction simple pour ce:

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

, Alors vous pouvez l'utiliser:

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

3.Désérialiser la chaîne json sans classe & & désérialiser Json avec des propriétés numériques

C'est un Json qui commence par un nombre ou propriétés numériques.

Par exemple:

{ 
"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 ne prend pas en charge cela car la propriété "15m" commence par un nombre. Une variable de classe ne peut pas commencer par un entier.

Télécharger SimpleJSON.cs à partir de l'Unité de wiki.

Pour obtenir la propriété" 15m " de USD:

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

Pour obtenir la propriété" 15m " De ISK:

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

Pour obtenir la propriété " 15m " de NZD:

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

Le reste des propriétés Json qui ne commencent pas par un chiffre numérique peut être géré par Jsonutility D'Unity.


4.Dépannage JsonUtility:

Problèmes lors de la sérialisation avec JsonUtility.ToJson?

Obtenir une chaîne vide ou "{}" avec JsonUtility.ToJson?

Un. Assurez-vous que la classe n'est pas un tableau. Si c'est le cas, utilisez la classe d'aide ci-dessus avec JsonHelper.ToJson au lieu de JsonUtility.ToJson.

B. Ajoutez [Serializable] en haut de la classe que vous sérialisez.

C. Supprimer la propriété de la classe. Par exemple, dans la variable, public string playerId { get; set; } supprimer { get; set; }. Unity ne peut pas sérialiser cela.

Problèmes lors de la désérialisation avec JsonUtility.FromJson?

Un. Si vous obtenez Null, assurez-vous que le Json n'est pas un tableau Json. Si c'est le cas, utilisez la classe d'aide ci-dessus avec JsonHelper.FromJson au lieu de JsonUtility.FromJson.

B. Si vous obtenez NullReferenceException lors de la désérialisation, ajoutez [Serializable] en haut de la classe.

C.Tout autre problème, vérifiez que votre json est valide. Allez sur ce site ici et collez le json. Il devrait vous montrer si le json est valide. Il devrait également générer la classe appropriée avec le Json. Assurez-vous simplement de supprimer supprimer { get; set; } à partir de chaque variable et ajoutez également [Serializable] en haut de chaque classe générée.


Newtonsoft.Json:

Si pour une raison quelconque Newtonsoft.Json doit être utilisé puis vérifier la version fourchue pour Unity ici . Notez que vous pouvez rencontrer un plantage si certaines fonctionnalités sont utilisées. Être prudent.


pour répondre À votre question:

Vos données d'origine sont

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

Ajouter {"Items": dans avant de il ajoute ensuite } à la fin de celui-ci.

Code pour ce faire:

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

Maintenant, vous avez:

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

À sérialiser le multiples données à partir de php tableaux, vous pouvez maintenant faire

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

playerInstance[0] est votre première donnée

playerInstance[1] est votre deuxième de données

playerInstance[2] est votre troisième de données

Ou données à l'intérieur de la classe avec playerInstance[0].playerLoc, playerInstance[1].playerLoc, playerInstance[2].playerLoc ......

Vous pouvez utiliser playerInstance.Length pour vérifier la longueur avant d'y accéder.

NOTE: Supprimer { get; set; } de la classe player. Si vous avez { get; set; }, cela ne fonctionnera pas. L'unité de JsonUtility ne PAS travailler avec les membres de la classe qui sont définis comme propriétés.

135
répondu Programmer 2017-08-23 10:31:54

Supposons que vous avez un JSON comme celui-ci

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

Pour analyser le JSON ci-dessus dans unity, vous pouvez créer un modèle JSON comme ceci.

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

Et ensuite simplement analyser de la manière suivante...

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

Maintenant, vous pouvez modifier le JSON / CODE en fonction de vos besoins. https://docs.unity3d.com/Manual/JSONSerialization.html

5
répondu Narottam Goyal 2018-08-06 09:43:48

Ne coupez pas le [] et vous devriez aller bien. [] identifiez un tableau JSON qui est exactement ce dont vous avez besoin pour pouvoir itérer ses éléments.

0
répondu Thomas Hilbert 2016-03-26 22:32:24

Comme l'a dit @ Maximiliangerhardt, les MiniJson n'ont pas la capacité de désérialiser correctement. J'ai utilisé JsonFx et fonctionne comme un charme. Fonctionne avec le []

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);
0
répondu dil33pm 2016-03-27 05:16:39

, Vous devez ajouter [System.Serializable] à PlayerItem classe ,comme ceci:

using System;
[System.Serializable]
public class PlayerItem   {
    public string playerId;
    public string playerLoc;
    public string playerNick;
}
0
répondu Myan 2016-12-05 07:53:55