У меня есть список элементов, отправленных из файла PHP в единство с использованием WWW
.
В WWW.text
выглядит следующим образом :
[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]
Где я обрезаю лишнее []
из string
. Когда я пытаюсь разобрать его с помощью Boomlagoon.JSON
, извлекается только первый объект. Я обнаружил, что у меня есть deserialize()
список, и импортировал MiniJSON.
Но я не понимаю, как deserialize()
этот список. Я хочу перебрать каждый объект 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> players = Json.Deserialize(serviceData) as IDictionary<string, object>;
foreach (KeyValuePair<string, object> kvp in players)
{
Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
}
Благодарность!
[
и]
? Вот что делает его списком. Просто прекратите удалять это и десериализуйте его как массив или список, и я ожидаю, что все будет в порядке. Пожалуйста, опубликуйте код, который вы пробовали.List<PlayerLocation>
, потому что это является массивом.Newtonsoft.Json
), ноJson.Deserialize()
ВСЕГДА возвращаетIDictionary<string,object>
вам, и вы выполняете операцииList<object>
. Посмотрите stackoverflow.com/a/22745634/5296568 . Желательно получить лучший десериализатор JSON, который выполняет десериализацию, к которой вы привыкли.IDictionary<string,object>
. Я могу получить ценность, но только первуюKeyValuePair<>
.Ответы:
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"}
Сериализация части 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" }
Десериализация части 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. НЕСКОЛЬКО ДАННЫХ (МАССИВ JSON)
Ваш Json содержит несколько объектов данных. Например
playerId
появлялся не раз . UnityJsonUtility
не поддерживает массив, поскольку он все еще новый, но вы можете использовать вспомогательный класс от этого человека, чтобы заставить работать массив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);
Выход :
Если это массив 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);
Чтобы получить собственность "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
.B . Добавьте
[Serializable]
в начало сериализуемого класса.C . Удалите свойство из класса. Например, в переменной
public string playerId { get; set; }
удалить{ get; set; }
. Unity не может сериализовать это.Проблемы при десериализации с помощью
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
это НЕ работать с членами класса , которые определяются как свойства .источник
mysql
запроса из PHP, используяjson_encode($row)
. Таким образом, ответ состоит из нескольких объектов JSONObject в формате[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
. Я попробовал JsonUtility, но не смог десериализовать объекты и получить отдельные объекты json. Если вы можете мне с этим помочь.JsonUtility.FromJson
. Я забыл сказать тебе, чтобы ты удалился{ get; set; }
изplayer
класса. Если да{ get; set; }
, это не сработает. Сравните вашplayer
класс с тем, что я опубликовал выше, и вы поймете, о чем я говорю.JsonHelper
. Это замечательно. Если вы создаете с ним Json, вы также можете читать с ним json без дополнительных действий. Единственный раз, когда вам может потребоваться дополнительная работа, - это если вы получаете массив json с сервера, и это включено в решение, в моем ответе. Другой способJsonHelper
- поместить класс в другой класс, а затем сделать его классомList
. Это работает для большинства людей. Если вы ищете способ сохранить и загрузить данные игры, посмотрите это . Вы загружаете и сохраняете с помощью одной строчки кода.Предположим, у вас есть такой JSON
[ { "type": "qrcode", "symbol": [ { "seq": 0, "data": "HelloWorld9887725216", "error": null } ] } ]
Чтобы проанализировать приведенный выше JSON в единстве, вы можете создать такую модель 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 / CODE в соответствии с вашими потребностями. https://docs.unity3d.com/Manual/JSONSerialization.html
источник
Debug.Log(myObject.result[0].symbol[0].data);
илиfor(var i = 0; i <= myObject.result.Length - 1; i ++) { Debug.Log(myObject.result[i].type); }
илиforeach (var item in myObject.result) { Debug.Log(item.type); }
вам нужно добавить
[System.Serializable]
вPlayerItem
класс, например:using System; [System.Serializable] public class PlayerItem { public string playerId; public string playerLoc; public string playerNick; }
источник
Чтобы прочитать файл JSON, обратитесь к этому простому примеру
Ваш файл JSON (StreamingAssets / Player.json)
{ "Name": "MyName", "Level": 4 }
C # скрипт
public class Demo { public void ReadJSON() { string path = Application.streamingAssetsPath + "/Player.json"; string JSONString = File.ReadAllText(path); Player player = JsonUtility.FromJson<Player>(JSONString); Debug.Log(player.Name); } } [System.Serializable] public class Player { public string Name; public int Level; }
источник
File.ReadAllText
который, на мой взгляд, полезен, и ни в одном другом ответе не упоминается :)Не обрезайте,
[]
и все будет в порядке.[]
идентифицировать массив 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);
источник
Вы можете
Newtonsoft.Json
просто добавитьNewtonsoft.dll
в свой проект и использовать сценарий нижеusing System; using Newtonsoft.Json; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { [Serializable] public class Person { public string id; public string name; } public Person[] person; private void Start() { var myjson = JsonConvert.SerializeObject(person); print(myjson); } }
другое решение использует JsonHelper
using System; using Newtonsoft.Json; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { [Serializable] public class Person { public string id; public string name; } public Person[] person; private void Start() { var myjson = JsonHelper.ToJson(person); print(myjson); } }
источник
ЕСЛИ вы используете Vector3, это то, что я сделал
1- Я создаю класс, назовите его Player
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; [Serializable] public class Player { public Vector3[] Position; }
2- тогда я называю это так
if ( _ispressed == true) { Player playerInstance = new Player(); playerInstance.Position = newPos; string jsonData = JsonUtility.ToJson(playerInstance); reference.Child("Position" + Random.Range(0, 1000000)).SetRawJsonValueAsync(jsonData); Debug.Log(jsonData); _ispressed = false; }
3- и это результат
источник
Единство <= 2019
У Нароттама Гояла была хорошая идея обернуть массив в json-объект, а затем десериализовать его в структуру. Далее для решения этой проблемы для массивов всех типов используются Generics, в отличие от создания нового класса каждый раз.
[System.Serializable] private struct JsonArrayWrapper<T> { public T wrap_result; } public static T ParseJsonArray<T>(string json) { var temp = JsonUtility.FromJson<JsonArrayWrapper<T>>("{\" wrap_result\":" + json + "}"); return temp.wrap_result; }
Его можно использовать следующим образом:
string[] options = ParseJsonArray<string[]>(someArrayOfStringsJson);
Единство 2020
В Unity 2020 есть официальный пакет newtonsoft , который представляет собой гораздо лучшую библиотеку json.
источник