Unity добавила JsonUtility в свой API после обновления 5.3.3. Забудьте обо всех сторонних библиотеках, если вы не делаете что-то более сложное. JsonUtility быстрее, чем другие библиотеки Json. Обновите Unity до версии 5.3.3 или более поздней и попробуйте решение, указанное ниже.
JsonUtility
- легкий API. Поддерживаются только простые типы. Он не поддерживает такие коллекции, как Dictionary. Одно исключение - 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 JSON
string playerToJson = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJson);
Вывод:
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
Сериализация части Б:
Сериализовать в 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 JSON
string playerToJson = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJson);
Вывод:
{
"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);
Десериализация части Б:
Десериализовать 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
появлялся более одного раза. JsonUtility
Unity не поддерживает массив, поскольку он все еще новый, но вы можете использовать helper от этого человека, чтобы получить массив, работающий с 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 JSON
string playerToJson = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJson);
Вывод:
{
"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
Пользователь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" : "$"}
}
JsonUtility
Unity не поддерживает это, потому что свойство «15m» начинается с числа. Переменная класса не может начинаться с целого числа.
Загрузите SimpleJSON.cs
из вики Unity.
Чтобы получить недвижимость «15 миллионов долларов»:
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);
Чтобы получить недвижимость NZD "15m":
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]
в начало сериализуемого класса.
В. Удалите свойство из класса. Например, в переменной public string playerId { get; set; }
удалить { get; set; }
. Unity не может сериализовать это.
Проблемы при десериализации с JsonUtility.FromJson
?
А. Если вы получили Null
, убедитесь, что Json не является массивом Json. Если это так, используйте указанный выше вспомогательный класс с JsonHelper.FromJson
вместо JsonUtility.FromJson
.
Б. Если при десериализации вы получите 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":
перед, затем добавьте }
в конце.
Код для этого:
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; }
, это не сработает. JsonUtility
Unity НЕ работает с членами класса, которые определены как свойства.
person
Programmer
schedule
27.03.2016
[
и]
? Вот что делает его списком. Просто прекратите удалять это и десериализуйте его как массив или список, и я ожидаю, что все будет в порядке. Пожалуйста, опубликуйте код, который вы пробовали. - person Jon Skeet   schedule 26.03.2016List<PlayerLocation>
, потому что этот является массивом. - person Maximilian Gerhardt   schedule 26.03.2016Newtonsoft.Json
), ноJson.Deserialize()
ВСЕГДА возвращает вамIDictionary<string,object>
, и вы работаете сList<object>
. Посмотрите на stackoverflow.com/a/22745634/5296568. Желательно получить лучший десериализатор JSON, который выполняет десериализацию, к которой вы привыкли. - person Maximilian Gerhardt   schedule 26.03.2016IDictionary<string,object>
. Я могу получить значение, но только первоеKeyValuePair<>
. - person dil33pm   schedule 27.03.2016