Сериализовать и десериализовать массив Json и JSON в Unity

у меня есть список элементов, отправленных из файла PHP в unity с помощью WWW. The WWW.text выглядит так:[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}] где я обрезаю дополнительный [] из строки. Когда я пытаюсь разобрать его с помощью Boomlagoon.JSON, извлекается только первый объект. Я узнал, что я должен deserialize() список и импортировали MiniJSON.

но я смущен, как десериализовать () этот список. Я хочу перебрать каждый объект JSON и получить данные. Как я могу сделать это в Unity, используя C#?

класс, который я использую

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

после подрезки [] Я могу проанализировать json с помощью MiniJSON. Но он возвращается только первым 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));
}

спасибо!

5 ответов


единство добавил JsonUtility к их API после 5.3.3 обновление. Забудьте обо всех сторонних библиотеках, если вы не делаете что-то более сложное. JsonUtility быстрее, чем другие библиотеки Json. Обновление до Unity 5.3.3 версия или выше, то попробуйте Решение ниже.

JsonUtility - это легкий API. Поддерживаются только простые типы. Это не поддержка коллекций, таких как словарь. Одно исключение is List. Он поддерживает List и List массив!

Если вам нужно, чтобы сериализовать Dictionary или сделайте что-то другое, кроме простой сериализации и десериализации простых типов данных, используйте сторонний API. В противном случае продолжайте чтение.

пример класса для сериализации:

[Serializable]
public class Player
{

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

1. ОДИН ОБЪЕКТ ДАННЫХ (НЕ МАССИВ JSON)

Сериализация Части A:

сериализовать к Json с 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:

сериализовать в Json с public static string ToJson(object obj, bool prettyPrint); способ перегрузки. Просто проходя 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:

десериализовать json с public static T FromJson(string json); способ перегрузки.

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

Десериализация Части B:

десериализовать json с public static object FromJson(string json, Type type); способ перегрузки.

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

Десериализация Часть C:

десериализовать json с public static void FromJsonOverwrite(string json, object objectToOverwrite); метод. Когда , это не новый экземпляр этого объекта десериализации будет создан. Он просто повторно использует экземпляр, который вы передаете, и перезаписывает его значения.

это эффективно и должно использоваться, если это возможно.

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. НЕСКОЛЬКО ДАННЫХ (МАССИВ JSON)

ваш Json содержит несколько объектов данных. Например больше, чем после. Единство 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 Массив:

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.Десериализовать строку 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" : "$"}
}
единства!--22--> не поддерживает это, потому что свойство " 15m начинается с числа. Переменная класса не может начинаться с целого числа.

скачать SimpleJSON.cs из Unity wiki.

чтобы получить свойство" 15m " USD:

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

чтобы получить свойство" 15m " ISK:

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

чтобы получить свойство" 15m " NZD:

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

остальные свойства Json, которые не начинаются с числовой цифры, могут обрабатываться Unity JsonUtility.


4.Устранение неполадок JsonUtility:

проблемы при сериализации с JsonUtility.ToJson?

получение пустой строки или"{}" с JsonUtility.ToJson?

A. Убедитесь, что класс не является массивом. Если это так, используйте вспомогательный класс выше с JsonHelper.ToJson вместо JsonUtility.ToJson.

B. Добавить [Serializable] к началу класса, который вы сериализуете.

C. Удалить свойство из класса. Например, в переменной public string playerId { get; set; } удалить { get; set; }. Unity не может сериализовать это.

проблемы при десериализации с JsonUtility.FromJson?

A. Если вы получите Null, убедитесь, что JSON не является массивом Json. Если это так, используйте вспомогательный класс выше с JsonHelper.FromJson вместо JsonUtility.FromJson.

B. Если вы получите NullReferenceException при десериализации, добавить [Serializable] к началу класса.

C.Любые другие проблемы, убедитесь, что ваш json действителен. Перейти на этот сайт здесь и вставьте json. Он должен показать вам, действителен ли json. Он также должен генерировать правильный класс с помощью Json. Просто убедитесь, что удалить удалить { get; set; } С каждой переменной, а также добавить [Serializable] в верхней части каждого класса сгенерированный.


Newtonsoft.В JSON:

если по какой-то причине Newtonsoft.В JSON необходимо использовать, а затем проверить раздвоенную версию для Unity здесь. Обратите внимание, что при использовании определенной функции может произойти сбой. Быть осторожным.


чтобы ответить на ваш вопрос:

ваши исходные данные

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

добавить {"Items": in перед то добавить } на конец его.

код:

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

теперь у вас есть:

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

до сериализовать the несколько данные из 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; }, это не будет работать. Единство JsonUtility тут не работа с членами класса, которые определены как свойства.


Предположим, у вас есть JSON, как это

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

чтобы проанализировать выше JSON в unity, вы можете создать 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/код в соответствии с вашими потребностями. https://docs.unity3d.com/Manual/JSONSerialization.html


не обрезать [] и вы должны быть хорошо. [] определите массив JSON, который является именно тем, что вам нужно для итерации его элементов.


Как сказал @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);

вы должны добавить [System.Serializable] to PlayerItem класс ,как это:

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