Mam listę elementów wysłanych z pliku PHP do Unity za pomocą WWW
.
Do WWW.text
wygląda następująco:
[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]
Gdzie przycinam dodatek []
z string
. Kiedy próbuję przeanalizować go przy użyciu Boomlagoon.JSON
, pobierany jest tylko pierwszy obiekt. Dowiedziałem się, że mam do deserialize()
listy i zaimportowałem MiniJSON.
Ale jestem zdezorientowany, jak do deserialize()
tej listy. Chcę przejrzeć każdy obiekt JSON i pobrać dane. Jak mogę to zrobić w Unity przy użyciu C #?
Klasa, której używam, to
public class player
{
public string playerId { get; set; }
public string playerLoc { get; set; }
public string playerNick { get; set; }
}
Po przycięciu []
jestem w stanie przeanalizować json za pomocą MiniJSON. Ale wraca tylko pierwszy 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));
}
Dzięki!
[
i]
? To właśnie sprawia, że jest to lista. Po prostu przestań to usuwać i zdeserializuj jako tablicę lub listę, a spodziewałbym się, że wszystko będzie dobrze. Wpisz kod, który próbowałeś.List<PlayerLocation>
, ponieważ jest to tablica.Newtonsoft.Json
), aleJson.Deserialize()
ZAWSZE zwracaIDictionary<string,object>
do ciebie i działasz dalejList<object>
. Spójrz na stackoverflow.com/a/22745634/5296568 . Najlepiej zdobądź lepszy deserializator JSON, który wykonuje deserializację, do której jesteś przyzwyczajony.IDictionary<string,object>
. Jestem w stanie wydobyć wartość, ale tylko pierwsząKeyValuePair<>
.Odpowiedzi:
Unity dodała JsonUtility do swojego API po aktualizacji 5.3.3 . Zapomnij o wszystkich bibliotekach innych firm, chyba że robisz coś bardziej skomplikowanego. JsonUtility jest szybsze niż inne biblioteki Json. Zaktualizuj do wersji Unity 5.3.3 lub nowszej, a następnie wypróbuj poniższe rozwiązanie.
JsonUtility
to lekki interfejs API. Obsługiwane są tylko proste typy. To nie nie obsługują kolekcji, takich jak hasła. Jedynym wyjątkiem jestList
. ObsługujeList
iList
szykuje!Jeśli chcesz serializować
Dictionary
lub zrobić coś innego niż po prostu serializować i deserializować proste typy danych, użyj interfejsu API innej firmy. W przeciwnym razie kontynuuj czytanie.Przykładowa klasa do serializacji:
[Serializable] public class Player { public string playerId; public string playerLoc; public string playerNick; }
1. JEDEN OBIEKT DANYCH (NON-ARRAY JSON)
Serializacja części A :
Serializuj do Json za pomocą
public static string ToJson(object obj);
metody.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);
Wyjście :
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
Serializacja części B :
Serializuj do Json z
public static string ToJson(object obj, bool prettyPrint);
przeciążeniem metody. Zwykłe przekazanietrue
doJsonUtility.ToJson
funkcji spowoduje sformatowanie danych. Porównaj dane wyjściowe poniżej z wynikami powyżej.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);
Wyjście :
{ "playerId": "8484239823", "playerLoc": "Powai", "playerNick": "Random Nick" }
Deserializacja część A :
Deserializacja json przy użyciu
public static T FromJson(string json);
przeciążenia metody.string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; Player player = JsonUtility.FromJson<Player>(jsonString); Debug.Log(player.playerLoc);
Deserializacja części B :
Deserializacja json przy użyciu
public static object FromJson(string json, Type type);
przeciążenia metody.string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player)); Debug.Log(player.playerLoc);
Deserializacja część C :
Deserializacja json za pomocą
public static void FromJsonOverwrite(string json, object objectToOverwrite);
metody. GdyJsonUtility.FromJsonOverwrite
jest używany, nie zostanie utworzone żadne nowe wystąpienie tego obiektu, do którego deserializujesz. Po prostu ponownie wykorzysta przekazaną instancję i nadpisze jej wartości.Jest to wydajne i powinno być używane, jeśli to możliwe.
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. WIELE DANYCH (ARRAY JSON)
Twoja Json zawiera wiele obiektów danych. Na przykład
playerId
pojawił się więcej niż raz . JednościJsonUtility
nie obsługuje tablicę, ponieważ jest jeszcze nowy, ale można użyć pomocnika klasy od tej osoby, aby uzyskać macierz pracuje zJsonUtility
.Utwórz klasę o nazwie
JsonHelper
. Skopiuj JsonHelper bezpośrednio od dołu.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; } }
Serializacja tablicy 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);
Wyjście :
{ "Items": [ { "playerId": "8484239823", "playerLoc": "Powai", "playerNick": "Random Nick" }, { "playerId": "512343283", "playerLoc": "User2", "playerNick": "Rand Nick 2" } ] }
Deserializacja tablicy 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);
Wyjście :
Jeśli to jest tablica Json z serwera i nie utworzyłeś jej ręcznie :
Być może trzeba będzie dodać
{"Items":
przed otrzymanym ciągiem, a następnie dodać}
na końcu.Zrobiłem w tym celu prostą funkcję:
string fixJson(string value) { value = "{\"Items\":" + value + "}"; return value; }
wtedy możesz go użyć:
string jsonString = fixJson(yourJsonFromServer); Player[] player = JsonHelper.FromJson<Player>(jsonString);
3. Deserializuj ciąg JSON bez klasy && De-serializacji Json z właściwościami numerycznymi
To jest Json, który zaczyna się od liczby lub właściwości numerycznych.
Na przykład:
{ "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
tego nie obsługuje, ponieważ właściwość „15m” zaczyna się od liczby. Zmienna klasy nie może zaczynać się od liczby całkowitej.Pobierz
SimpleJSON.cs
z wiki Unity .Aby uzyskać właściwość „15m” w USD:
var N = JSON.Parse(yourJsonString); string price = N["USD"]["15m"].Value; Debug.Log(price);
Aby uzyskać własność ISK „15m”:
var N = JSON.Parse(yourJsonString); string price = N["ISK"]["15m"].Value; Debug.Log(price);
Aby uzyskać własność „15 m” NZD:
var N = JSON.Parse(yourJsonString); string price = N["NZD"]["15m"].Value; Debug.Log(price);
Pozostałe właściwości Json, które nie zaczynają się od cyfry, mogą być obsługiwane przez JsonUtility Unity.
4. ROZWIĄZYWANIE PROBLEMÓW JsonUtility:
Problemy podczas serializacji z
JsonUtility.ToJson
?Otrzymujesz pusty ciąg lub „
{}
” zJsonUtility.ToJson
?. Upewnij się, że klasa nie jest tablicą. Jeśli tak, użyj powyższej klasy pomocniczej z
JsonHelper.ToJson
zamiastJsonUtility.ToJson
.B . Dodaj
[Serializable]
na początku klasy, którą serializujesz.C . Usuń właściwość z klasy. Na przykład w zmiennej
public string playerId { get; set; }
remove{ get; set; }
. Unity nie może tego serializować.Problemy podczas deserializacji z
JsonUtility.FromJson
?. Jeśli otrzymasz
Null
, upewnij się, że Json nie jest tablicą Json. Jeśli tak, użyj powyższej klasy pomocniczej zJsonHelper.FromJson
zamiastJsonUtility.FromJson
.B . Jeśli otrzymasz
NullReferenceException
podczas deserializacji, dodaj[Serializable]
do początku klasy.C .Wszelkie inne problemy, sprawdź, czy plik json jest prawidłowy. Przejdź do tej witryny tutaj i wklej plik json. Powinien pokazać, czy plik json jest prawidłowy. Powinien również wygenerować odpowiednią klasę z Json. Po prostu pamiętaj, aby usunąć usuń
{ get; set; }
z każdej zmiennej, a także dodaj[Serializable]
na początku każdej wygenerowanej klasy.Newtonsoft.Json:
Jeśli z jakiegoś powodu Newtonsoft.Json należy stosować wtedy sprawdzić wersję rozdwojony Jedności tutaj . Pamiętaj, że może wystąpić awaria, jeśli używana jest określona funkcja. Bądź ostrożny.
Aby odpowiedzieć na Twoje pytanie :
Twoje oryginalne dane to
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
Dodaj
{"Items":
do przodu o to następnie dodać}
na końcu tego.Kod, aby to zrobić:
serviceData = "{\"Items\":" + serviceData + "}";
Teraz masz:
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
Do serializacji do wielu danych z PHP jako tablic , można teraz zrobić
public player[] playerInstance; playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
to twoje pierwsze daneplayerInstance[1]
to twoje drugie daneplayerInstance[2]
to Twoje trzecie danelub danych wewnątrz klasy z
playerInstance[0].playerLoc
,playerInstance[1].playerLoc
,playerInstance[2].playerLoc
......Możesz użyć,
playerInstance.Length
aby sprawdzić długość przed uzyskaniem do niego dostępu.UWAGA: Usuń
{ get; set; }
zplayer
zajęć. Jeśli tak{ get; set; }
, to nie zadziała. UnityJsonUtility
ma NIE pracować z członków klasy, które są zdefiniowane jako właściwości .źródło
mysql
zapytania z PHP przy użyciujson_encode($row)
. Zatem odpowiedź składa się z wielu obiektów JSONObject w formacie[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
. Próbowałem JsonUtility, ale nie mogłem deserializować obiektów i uzyskiwać pojedynczych obiektów json. Jeśli możesz mi w tym pomóc.JsonUtility.FromJson
. Zapomniałem ci powiedzieć, żebyś usunął się{ get; set; }
zplayer
klasy. Jeśli tak{ get; set; }
, to nie zadziała. Porównaj swojąplayer
klasę z tą, którą zamieściłem powyżej, a zrozumiesz, o czym mówię.JsonHelper
. W porządku. Jeśli utworzysz z nim Json, możesz również czytać json z nim bez dodatkowych kroków. Jedyny przypadek, w którym będziesz musiał zrobić dodatkowe rzeczy, to jeśli otrzymujesz tablicę json z serwera i to jest zawarte w rozwiązaniu, jest w mojej odpowiedzi. Innym sposobemJsonHelper
jest umieszczenie klasy w innej klasie, a następnie nadanie jejList
. To działa dla większości ludzi. Jeśli szukasz sposobu na zapisywanie i ładowanie danych gry, zobacz to . Ładujesz i zapisujesz za pomocą jednej linii kodu.Załóżmy, że masz taki JSON
[ { "type": "qrcode", "symbol": [ { "seq": 0, "data": "HelloWorld9887725216", "error": null } ] } ]
Aby przeanalizować powyższy JSON w jedności, możesz utworzyć model JSON w ten sposób.
[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; }
A następnie po prostu przeanalizuj w następujący sposób ...
var myObject = JsonUtility.FromJson<QrCodeResult>("{\"result\":" + jsonString.ToString() + "}");
Teraz możesz zmodyfikować JSON / CODE zgodnie ze swoimi potrzebami. https://docs.unity3d.com/Manual/JSONSerialization.html
źródło
Debug.Log(myObject.result[0].symbol[0].data);
lubfor(var i = 0; i <= myObject.result.Length - 1; i ++) { Debug.Log(myObject.result[i].type); }
lubforeach (var item in myObject.result) { Debug.Log(item.type); }
musisz dodać
[System.Serializable]
doPlayerItem
klasy, w ten sposób:using System; [System.Serializable] public class PlayerItem { public string playerId; public string playerLoc; public string playerNick; }
źródło
Aby przeczytać plik JSON, zapoznaj się z tym prostym przykładem
Twój plik JSON (StreamingAssets / Player.json)
{ "Name": "MyName", "Level": 4 }
Skrypt 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; }
źródło
File.ReadAllText
które moim zdaniem jest pomocne i żadna inna odpowiedź nie wspomina :)Nie przycinaj
[]
i powinno być dobrze.[]
zidentyfikuj tablicę JSON, która jest dokładnie tym, czego potrzebujesz, aby móc iterować jej elementy.źródło
Jak powiedział @Maximiliangerhardt, MiniJson nie ma możliwości prawidłowej deserializacji. Użyłem JsonFx i działa jak urok. Działa z
[]
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);
źródło
Możesz użyć
Newtonsoft.Json
po prostu dodajNewtonsoft.dll
do swojego projektu i użyj poniższego skryptuusing 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); } }
innym rozwiązaniem jest użycie 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); } }
źródło
JEŚLI używasz Vector3, to właśnie zrobiłem
1- Tworzę klasę Nazwij ją Gracz
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; [Serializable] public class Player { public Vector3[] Position; }
2 - wtedy nazywam to tak
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- i to jest wynik
źródło
Jedność <= 2019
Narottam Goyal miał dobry pomysł na zawinięcie tablicy w obiekt json, a następnie deserializację do struktury. W poniższym przykładzie zastosowano Generics do rozwiązania tego problemu dla tablic wszystkich typów, w przeciwieństwie do tworzenia nowej klasy za każdym razem.
[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; }
Można go używać w następujący sposób:
string[] options = ParseJsonArray<string[]>(someArrayOfStringsJson);
Jedność 2020
W Unity 2020 jest oficjalny pakiet Newtonsoft , który jest znacznie lepszą biblioteką json.
źródło