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)
Серіалізація частини А :
Серіалізуйте 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"}
Серіалізація частини 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 JSON
string playerToJson = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJson);
Вихід :
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}
Десериалізація частини А :
Десеріалізуйте 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
не підтримує масив , як це все ще новий , але ви можете використовувати допоміжний клас від цієї людини , щоб отримати масив роботи з 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);
Вихід :
Повай
Користувач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" : "$"}
}
Unity's JsonUtility
цього не підтримує, оскільки властивість "15 м" починається з числа. Змінна класу не може починатися з цілого числа.
Завантажте SimpleJSON.cs
з вікі Unity .
Щоб отримати майно "15 млн. Доларів США":
var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);
Щоб отримати властивість ISK "15 м":
var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);
Щоб отримати власність NZD "15 м":
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
Решта властивостей Json, які не починаються з числової цифри, можна обробляти за допомогою JsonUtility Unity.
4. УСУНЕННЯ НЕСПРАВНОСТЕЙ JsonUtility:
Проблеми при серіалізації з JsonUtility.ToJson
?
Отримання порожнього рядка або " {}
" з JsonUtility.ToJson
?
. Переконайтесь, що клас не є масивом. Якщо це так, використовуйте допоміжний клас вище з JsonHelper.ToJson
замість JsonUtility.ToJson
.
B . Додайте [Serializable]
до верхньої частини класу, який ви серіалізуєте.
C . Видаліть властивість із класу. Наприклад, у змінній public string playerId { get; set; }
видаліть { get; set; }
. Єдність не може серіалізувати це.
Проблеми при десериалізації з JsonUtility.FromJson
?
. Якщо ви отримаєте Null
, переконайтеся, що Json не є масивом Json. Якщо це так, використовуйте допоміжний клас вище з JsonHelper.FromJson
замість JsonUtility.FromJson
.
B . Якщо ви отримуєте 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":
в передній області , потім додати }
в кінці цього.
Код для цього:
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
це НЕ працювати з членами класу , які визначаються як властивості .
[
і]
? Ось що робить його списком. Просто припиніть видаляти це та десеріалізуйте його як масив або список, і я сподівався б, що це буде добре. Будь ласка, опублікуйте код, який ви спробували.