Ответ 1
Unity добавил JsonUtility в их API после 5.3.3 обновления. Забудьте обо всех сторонних библиотеках, если вы не делаете что-то более сложное. JsonUtility работает быстрее, чем другие библиотеки Json. Обновите Unity до версии 5.3.3 или выше, затем попробуйте решение ниже.
JsonUtility
- это легкий API. Поддерживаются только простые типы. Он не поддерживает коллекции, такие как словарь. Единственным исключением является 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);
. Когда используется 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
не поддерживает массив, так как он все еще новый, но вы можете использовать вспомогательный класс от этого человека, чтобы массив работал с 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);
Выход:
Powai
User2
Если это массив 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" : "$"}
}
Unity JsonUtility
не поддерживает это, потому что свойство "15m" начинается с числа. Переменная класса не может начинаться с целого числа.
Загрузите SimpleJSON.cs
из Unity вики.
Чтобы получить собственность в 15 млн. Долларов США:
var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);
Чтобы получить свойство "15 м" ISK:
var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);
Чтобы получить свойство "15 м" от NZD:
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
Остальные свойства Json, которые не начинаются с цифры, могут обрабатываться Unity JsonUtility.
4. УСТРАНЕНИЕ НЕИСПРАВНОСТЕЙ JsonUtility:
Проблемы при сериализации с JsonUtility.ToJson
?
Получение пустой строки или "{}
" с помощью JsonUtility.ToJson
?
. Убедитесь, что класс не является массивом. Если это так, используйте вспомогательный класс выше с JsonHelper.ToJson
вместо JsonUtility.ToJson
.
В. Добавьте [Serializable]
в начало класса, который вы сериализуете.
C. Удалить свойство из класса. Например, в переменной public string playerId { get; set; }
remove { get; set; }
. Unity не может сериализовать это.
Проблемы при десериализации с JsonUtility.FromJson
?
. Если вы получите Null
, убедитесь, что Json не является массивом Json. Если это так, используйте вспомогательный класс выше с JsonHelper.FromJson
вместо JsonUtility.FromJson
.
В. Если вы получили NullReferenceException
во время десериализации, добавьте [Serializable]
в начало класса.
C. Любые другие проблемы, убедитесь, что ваш JSON действителен. Перейдите на этот сайт здесь и вставьте JSON. Он должен показать вам, если JSON действителен. Он также должен генерировать правильный класс с Json. Просто удалите remove { get; set; }
из каждой переменной, а также добавьте [Serializable]
в начало каждого сгенерированного класса.
Newtonsoft.Json:
Если по какой-либо причине необходимо использовать Newtonsoft.Json, ознакомьтесь с разветвленной версией Unity здесь. Обратите внимание, что вы можете столкнуться с падением при использовании определенной функции. Будьте осторожны.
Чтобы ответить на ваш вопрос:
Ваши исходные данные
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
Добавьте {"Items":
впереди front и затем добавьте }
на конце.
Код для этого:
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
НЕ работает с членами класса, которые определены как свойства.