Saya memiliki daftar item yang dikirim dari file PHP ke unity WWW
.
The WWW.text
terlihat seperti:
[
{
"playerId": "1",
"playerLoc": "Powai"
},
{
"playerId": "2",
"playerLoc": "Andheri"
},
{
"playerId": "3",
"playerLoc": "Churchgate"
}
]
Di mana saya memangkas ekstra []
dari string
. Ketika saya mencoba mengurai menggunakan Boomlagoon.JSON
, hanya objek pertama yang diambil. Saya menemukan bahwa saya harus deserialize()
daftar dan telah mengimpor MiniJSON.
Tapi saya bingung bagaimana cara deserialize()
daftar ini. Saya ingin mengulang setiap objek JSON dan mengambil data. Bagaimana saya bisa melakukan ini di Unity menggunakan C #?
Kelas yang saya gunakan adalah
public class player
{
public string playerId { get; set; }
public string playerLoc { get; set; }
public string playerNick { get; set; }
}
Setelah pemangkasan, []
saya dapat mengurai json menggunakan MiniJSON. Tapi itu hanya kembali yang pertama 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));
}
Terima kasih!
[
dan]
? Itulah yang membuatnya menjadi sebuah daftar. Berhenti saja menghapusnya, dan deserialize sebagai array atau daftar dan saya berharap itu baik-baik saja. Silakan posting kode yang Anda coba.List<PlayerLocation>
, karena ini adalah array.Newtonsoft.Json
), tetapiJson.Deserialize()
SELALU mengembalikan aIDictionary<string,object>
kepada Anda dan Anda beroperasiList<object>
. Lihat stackoverflow.com/a/22745634/5296568 . Lebih disukai, dapatkan deserializer JSON yang lebih baik yang melakukan deserialisasi yang biasa Anda lakukan.IDictionary<string,object>
. Saya bisa mengeluarkan nilainya, tetapi hanya yang pertamaKeyValuePair<>
.Jawaban:
Unity menambahkan JsonUtility ke API mereka setelah Pembaruan 5.3.3 . Lupakan semua pustaka pihak ketiga kecuali Anda melakukan sesuatu yang lebih rumit. JsonUtility lebih cepat daripada perpustakaan Json lainnya. Perbarui ke versi Unity 5.3.3 atau lebih tinggi, lalu coba solusi di bawah ini.
JsonUtility
adalah API ringan. Hanya tipe sederhana yang didukung. Itu tidak mendukung koleksi seperti Kamus. Satu pengecualian adalahList
. Ini mendukungList
danList
array!Jika Anda perlu membuat serial
Dictionary
atau melakukan sesuatu selain hanya membuat serial dan deserialisasi tipe data sederhana, gunakan API pihak ketiga. Jika tidak, lanjutkan membaca.Contoh kelas untuk membuat serial:
[Serializable] public class Player { public string playerId; public string playerLoc; public string playerNick; }
1. SATU OBYEK DATA (NON-ARRAY JSON)
Serialisasi Bagian A :
Serialisasi ke Json dengan
public static string ToJson(object obj);
metode.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);
Keluaran :
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
Serialisasi Bagian B :
Serialisasi ke Json dengan
public static string ToJson(object obj, bool prettyPrint);
metode overload. Hanya meneruskantrue
keJsonUtility.ToJson
fungsi tersebut akan memformat data. Bandingkan keluaran di bawah dengan keluaran di atas.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);
Keluaran :
{ "playerId": "8484239823", "playerLoc": "Powai", "playerNick": "Random Nick" }
Deserialisasi Bagian A :
Deserialisasi json dengan
public static T FromJson(string json);
metode overload.string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; Player player = JsonUtility.FromJson<Player>(jsonString); Debug.Log(player.playerLoc);
Deserialisasi Bagian B :
Deserialisasi json dengan
public static object FromJson(string json, Type type);
metode overload.string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player)); Debug.Log(player.playerLoc);
Deserialisasi Bagian C :
Deserialisasi json dengan
public static void FromJsonOverwrite(string json, object objectToOverwrite);
metode. SaatJsonUtility.FromJsonOverwrite
digunakan, tidak ada instance baru dari Objek yang Anda deserialisasi akan dibuat. Ini hanya akan menggunakan kembali contoh yang Anda berikan dan menimpa nilainya.Ini efisien dan harus digunakan jika memungkinkan.
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. GANDA DATA (ARRAY JSON)
Json Anda berisi beberapa objek data. Misalnya
playerId
muncul lebih dari sekali . UnityJsonUtility
tidak mendukung array yang karena masih baru tapi Anda dapat menggunakan penolong kelas dari orang ini untuk mendapatkan berbagai bekerja denganJsonUtility
.Buat kelas bernama
JsonHelper
. Salin JsonHelper langsung dari bawah.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; } }
Serialisasi Json Array :
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);
Keluaran :
{ "Items": [ { "playerId": "8484239823", "playerLoc": "Powai", "playerNick": "Random Nick" }, { "playerId": "512343283", "playerLoc": "User2", "playerNick": "Rand Nick 2" } ] }
Deserialisasi Json Array :
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);
Keluaran :
Jika ini adalah array Json dari server dan Anda tidak membuatnya dengan tangan :
Anda mungkin harus menambahkan
{"Items":
di depan string yang diterima lalu menambahkan}
di akhir.Saya membuat fungsi sederhana untuk ini:
string fixJson(string value) { value = "{\"Items\":" + value + "}"; return value; }
maka Anda dapat menggunakannya:
string jsonString = fixJson(yourJsonFromServer); Player[] player = JsonHelper.FromJson<Player>(jsonString);
3. Deserialisasi string json tanpa class && De-serializing Json dengan properti numerik
Ini adalah Json yang dimulai dengan angka atau properti numerik.
Sebagai contoh:
{ "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
tidak mendukung ini karena properti "15m" dimulai dengan angka. Variabel kelas tidak dapat dimulai dengan bilangan bulat.Unduh
SimpleJSON.cs
dari wiki Unity .Untuk mendapatkan properti "15 juta" dari USD:
var N = JSON.Parse(yourJsonString); string price = N["USD"]["15m"].Value; Debug.Log(price);
Untuk mendapatkan properti "15m" dari ISK:
var N = JSON.Parse(yourJsonString); string price = N["ISK"]["15m"].Value; Debug.Log(price);
Untuk mendapatkan properti "15m" dari NZD:
var N = JSON.Parse(yourJsonString); string price = N["NZD"]["15m"].Value; Debug.Log(price);
Properti Json lainnya yang tidak dimulai dengan digit numerik dapat ditangani oleh JsonUtility Unity.
4. PEMECAHAN MASALAH JsonUtility:
Masalah saat membuat serial dengan
JsonUtility.ToJson
?Mendapatkan string kosong atau "
{}
" denganJsonUtility.ToJson
?A . Pastikan bahwa kelas tersebut bukan array. Jika ya, gunakan kelas helper di atas dengan
JsonHelper.ToJson
sebagai gantiJsonUtility.ToJson
.B . Tambahkan
[Serializable]
ke atas kelas Anda membuat serial.C . Hapus properti dari kelas. Misalnya, di variabel,
public string playerId { get; set; }
hapus{ get; set; }
. Unity tidak dapat membuat serial ini.Masalah saat melakukan deserialisasi
JsonUtility.FromJson
?A . Jika Anda mendapatkan
Null
, pastikan bahwa Json bukan array Json. Jika ya, gunakan kelas helper di atas denganJsonHelper.FromJson
sebagai gantiJsonUtility.FromJson
.B . Jika Anda mendapatkan
NullReferenceException
waktu deserialisasi, tambahkan[Serializable]
ke bagian atas kelas.C. Masalah lainnya, pastikan json Anda valid. Buka situs ini di sini dan tempel json. Ini akan menunjukkan kepada Anda apakah json valid. Itu juga harus menghasilkan kelas yang tepat dengan Json. Pastikan untuk menghapus remove
{ get; set; }
dari setiap variabel dan juga tambahkan[Serializable]
ke bagian atas setiap kelas yang dihasilkan.Newtonsoft.Json:
Jika karena alasan tertentu Newtonsoft.Json harus digunakan, periksa versi fork untuk Unity di sini . Perhatikan bahwa Anda mungkin mengalami crash jika fitur tertentu digunakan. Hati-hati.
Untuk menjawab pertanyaan Anda :
Data asli Anda adalah
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
Tambahkan
{"Items":
di depannya lalu tambahkan}
di ujungnya .Kode untuk melakukan ini:
serviceData = "{\"Items\":" + serviceData + "}";
Sekarang kamu punya:
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
Untuk cerita bersambung yang beberapa data dari php sebagai array , Anda sekarang dapat melakukan
public player[] playerInstance; playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
adalah data pertamamuplayerInstance[1]
adalah data kedua AndaplayerInstance[2]
adalah data ketiga Andaatau data di dalam kelas dengan
playerInstance[0].playerLoc
,playerInstance[1].playerLoc
,playerInstance[2].playerLoc
......Anda dapat menggunakan
playerInstance.Length
untuk memeriksa panjangnya sebelum mengaksesnya.CATATAN: Hapus
{ get; set; }
dariplayer
kelas. Jika sudah{ get; set; }
, itu tidak akan berhasil. UnityJsonUtility
tidak TIDAK bekerja dengan anggota kelas yang didefinisikan sebagai sifat .sumber
mysql
kueri dari PHP menggunakanjson_encode($row)
. Jadi responsnya terdiri dari beberapa JSONObject dalam format[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
. Saya mencoba JsonUtility, tetapi saya tidak bisa menghilangkan nama objek dan mendapatkan objek json individual. Jika Anda dapat membantu saya dengan itu.JsonUtility.FromJson
. Saya lupa memberitahu Anda untuk keluar{ get; set; }
dariplayer
kelas. Jika sudah{ get; set; }
, itu tidak akan berhasil. Bandingkanplayer
kelas Anda dengan kelas yang saya posting di atas dan Anda akan mengerti apa yang saya katakan.JsonHelper
. Tidak apa-apa. Jika Anda membuat Json dengannya, Anda juga dapat membaca json dengannya tanpa langkah tambahan. Satu-satunya saat Anda mungkin perlu melakukan hal-hal tambahan adalah jika Anda menerima array json dari server dan yang termasuk dalam solusi ada di jawaban saya. Cara lain tanpanyaJsonHelper
adalah dengan menempatkan kelas di kelas lain kemudian menjadikannya aList
. Ini telah berhasil bagi kebanyakan orang. Jika Anda mencari cara untuk menyimpan dan memuat data game, lihat ini . Anda memuat dan menyimpan dengan satu baris kode.Asumsikan Anda mendapatkan JSON seperti ini
[ { "type": "qrcode", "symbol": [ { "seq": 0, "data": "HelloWorld9887725216", "error": null } ] } ]
Untuk mengurai JSON di atas menjadi satu, Anda dapat membuat model JSON seperti ini.
[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; }
Dan kemudian cukup parsing dengan cara berikut ...
var myObject = JsonUtility.FromJson<QrCodeResult>("{\"result\":" + jsonString.ToString() + "}");
Sekarang Anda dapat memodifikasi JSON / CODE sesuai kebutuhan Anda. https://docs.unity3d.com/Manual/JSONSerialization.html
sumber
Debug.Log(myObject.result[0].symbol[0].data);
ataufor(var i = 0; i <= myObject.result.Length - 1; i ++) { Debug.Log(myObject.result[i].type); }
atauforeach (var item in myObject.result) { Debug.Log(item.type); }
Anda harus menambahkan
[System.Serializable]
kePlayerItem
kelas, seperti ini:using System; [System.Serializable] public class PlayerItem { public string playerId; public string playerLoc; public string playerNick; }
sumber
Untuk Membaca File JSON, lihat contoh sederhana ini
File JSON Anda (StreamingAssets / Player.json)
{ "Name": "MyName", "Level": 4 }
C # Script
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; }
sumber
File.ReadAllText
yang menurut saya membantu dan tidak ada jawaban lain yang menyebutkan :)Jangan memangkasnya
[]
dan Anda akan baik-baik saja.[]
mengidentifikasi larik JSON yang persis seperti yang Anda perlukan untuk dapat mengulang elemennya.sumber
Seperti yang dikatakan @Maximiliangerhardt, MiniJson tidak memiliki kemampuan untuk melakukan deserialisasi dengan benar. Saya menggunakan JsonFx dan bekerja dengan sangat baik. Bekerja dengan
[]
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);
sumber
Anda dapat menggunakan
Newtonsoft.Json
cukup tambahkanNewtonsoft.dll
ke proyek Anda dan gunakan skrip di bawah iniusing 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); } }
solusi lain adalah menggunakan 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); } }
sumber
JIKA Anda menggunakan Vector3, inilah yang saya lakukan
1- Saya membuat kelas Beri nama Player
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; [Serializable] public class Player { public Vector3[] Position; }
2- lalu saya menyebutnya seperti ini
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- dan inilah hasilnya
sumber
Unity <= 2019
Narottam Goyal memiliki ide yang bagus untuk membungkus array dalam objek json, dan kemudian melakukan deserialisasi menjadi struct. Berikut ini menggunakan Generik untuk memecahkan masalah ini untuk semua tipe array, sebagai lawan untuk membuat kelas baru setiap saat.
[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; }
Ini dapat digunakan dengan cara berikut:
string[] options = ParseJsonArray<string[]>(someArrayOfStringsJson);
Unity 2020
Di Unity 2020 ada paket newtonsoft resmi yang merupakan perpustakaan json yang jauh lebih baik.
sumber