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. วัตถุประสงค์ข้อมูลหนึ่งรายการ (NON-ARRAY JSON)
การทำให้เป็นอนุกรมส่วน A :
อนุกรมกับ Json ด้วยpublic static string ToJson(object obj);
วิธีการ
Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";
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";
string playerToJson = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJson);
เอาท์พุต :
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}
Deserializing ส่วน A :
Deserialize json ด้วยpublic static T FromJson(string json);
method overload
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);
Deserializing ส่วน B :
Deserialize json ด้วยpublic static object FromJson(string json, Type type);
method overload
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);
Deserializing ส่วน C :
Deserialize json ด้วยpublic static void FromJsonOverwrite(string json, object objectToOverwrite);
วิธีการ เมื่อJsonUtility.FromJsonOverwrite
ถูกใช้จะไม่มีการสร้างอินสแตนซ์ใหม่ของ Object นั้นที่คุณกำลัง deserializing จะถูกสร้างขึ้น มันจะนำอินสแตนซ์ที่คุณส่งผ่านไปใช้ซ้ำและเขียนทับค่าของมัน
สิ่งนี้มีประสิทธิภาพและควรใช้ถ้าเป็นไปได้
Player playerInstance;
void Start()
{
playerInstance = new Player();
deserialize();
}
void deserialize()
{
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
JsonUtility.FromJsonOverwrite(jsonString, playerInstance);
Debug.Log(playerInstance.playerLoc);
}
2. ข้อมูลหลายรายการ (ARRAY JSON)
Json ของคุณมีออบเจ็กต์ข้อมูลหลายตัว ยกตัวอย่างเช่นplayerId
ที่ปรากฏมากกว่าหนึ่งครั้ง Unity 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 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";
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"
}
]
}
Deserializing 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);
เอาท์พุต :
Powai
ผู้ใช้ 2
หากนี่คืออาร์เรย์ Json จากเซิร์ฟเวอร์และคุณไม่ได้สร้างด้วยมือ :
คุณอาจจะต้องเพิ่ม{"Items":
หน้าสตริงที่ได้รับจากนั้นเพิ่ม}
ที่ส่วนท้ายของสตริง
ฉันสร้างฟังก์ชันง่ายๆสำหรับสิ่งนี้:
string fixJson(string value)
{
value = "{\"Items\":" + value + "}";
return value;
}
จากนั้นคุณสามารถใช้งานได้:
string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);
3. deserialize สตริง json โดยไม่มีคลาส && De-serializing 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
ไม่รองรับสิ่งนี้เนื่องจากคุณสมบัติ "15m" เริ่มต้นด้วยตัวเลข ตัวแปรคลาสไม่สามารถเริ่มต้นด้วยจำนวนเต็ม
ดาวน์โหลดSimpleJSON.cs
จากความสามัคคีของวิกิพีเดีย
หากต้องการรับทรัพย์สิน "15m" ของ USD:
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);
หากต้องการรับคุณสมบัติ "15m" ของ NZD:
var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);
คุณสมบัติ Json ที่เหลือที่ไม่ได้ขึ้นต้นด้วยตัวเลขสามารถจัดการได้โดย JsonUtility ของ Unity
4. การแก้ปัญหา Json
ปัญหาในการต่ออนุกรมกับJsonUtility.ToJson
?
รับสตริงว่างหรือ " {}
" ด้วยJsonUtility.ToJson
?
ก . ตรวจสอบให้แน่ใจว่าคลาสไม่ใช่อาร์เรย์ ถ้าเป็นเช่นนั้นให้ใช้คลาสตัวช่วยด้านบนJsonHelper.ToJson
แทนJsonUtility.ToJson
ด้วย
ข . เพิ่ม[Serializable]
ที่ด้านบนสุดของคลาสที่คุณกำลังต่ออนุกรม
ค . ลบคุณสมบัติออกจากคลาส ยกตัวอย่างเช่นในตัวแปรลบpublic string playerId { get; set; }
{ get; set; }
Unity ไม่สามารถทำให้เป็นอนุกรมได้
ปัญหาเมื่อ deserializing ด้วยJsonUtility.FromJson
?
ก . ถ้าคุณได้รับNull
ตรวจสอบให้แน่ใจว่า Json ไม่ใช่อาร์เรย์ Json ถ้าเป็นเช่นนั้นให้ใช้คลาสตัวช่วยด้านบนJsonHelper.FromJson
แทนJsonUtility.FromJson
ด้วย
ข . หากคุณได้รับNullReferenceException
ขณะ deserializing ให้เพิ่ม[Serializable]
ที่ด้านบนสุดของชั้นเรียน
C.ปัญหาอื่น ๆ ตรวจสอบว่า json ของคุณถูกต้อง ไปที่ไซต์นี้ที่นี่และวาง json ควรแสดงให้คุณเห็นว่า json ถูกต้องหรือไม่ นอกจากนี้ยังควรสร้างคลาสที่เหมาะสมด้วย Json อย่าลืมลบลบ ออก { get; set; }
จากแต่ละตัวแปรและเพิ่ม[Serializable]
ที่ด้านบนของแต่ละคลาสที่สร้างขึ้น
Newtonsoft.Json:
หากมีเหตุผลบางNewtonsoft.Jsonจะต้องใช้แล้วตรวจสอบรุ่นคดเคี้ยวสามัคคีที่นี่ โปรดทราบว่าคุณอาจพบข้อขัดข้องหากใช้คุณลักษณะบางอย่าง ระวัง.
เพื่อตอบคำถามของคุณ :
ข้อมูลเดิมของคุณคือ
[{"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
ไม่ไม่ทำงานร่วมกับสมาชิกชั้นเรียนที่จะถูกกำหนดเป็นคุณสมบัติ
[
และ]
? นั่นคือสิ่งที่ทำให้เป็นรายการ เพียงแค่หยุดการลบสิ่งนั้นและกำหนดค่าเริ่มต้นเป็นอาร์เรย์หรือรายการและฉันคาดหวังว่ามันจะดี กรุณาโพสต์รหัสที่คุณได้ลองใช้