1.什麼是Json?
JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。它基於ECMAScript的一個子集。 JSON採用完全獨立於語言的文字格式,但是也使用了類似於C語言家族的習慣(包括C、C 、C#、Java、JavaScript、Perl、Python等)。這些特性使JSON成為理想的資料交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成(一般用於提升網路傳輸速率)。
2.JSON 語法規則
–資料在鍵值對中
–資料由逗號分隔
–花括號儲存物件
–方括號儲存陣列
–資料由逗號分隔
–花括號儲存物件
–方括號儲存陣列
舉例:
{"health": 100.0,
"money": 2500,
"Turing": [
"sword",
"shield",
"gun",
"woman",
"fruit"
]
}
3.Json的結構
–物件:物件在js中表示為“{}”括起來的內容,資料結構為 {key:value,key:value,…}的鍵值對的結構,在物件導向的語言中,key為物件的屬性,value為對應的屬性值,所以很容易理解,取值方法為 物件.key 獲取屬性值,這個屬性值的型別可以是 數字、字串、陣列、物件幾種。
–陣列:陣列在js中是中括號“[]”括起來的內容,資料結構為 [“java”,”javascript”,”vb”,…],取值方式和所有語言中一樣,使用索引獲取,欄位值的型別可以是 數字、字串、陣列、物件幾種。
–陣列:陣列在js中是中括號“[]”括起來的內容,資料結構為 [“java”,”javascript”,”vb”,…],取值方式和所有語言中一樣,使用索引獲取,欄位值的型別可以是 數字、字串、陣列、物件幾種。
開始實作:
Serialize模式A
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class JsonDemo2 : MonoBehaviour
{
//要儲存的物件或是陣列用一個Class去儲存,裡面可以放各類型的資料
[SerializeField]
public class Data2
{
public float health;
public int money;
public List<string> Turing;
}
void Start()
{
//宣告一個List作為道具列表並存入四個物件
List<string> equips = new List<string>();
equips.Add("sword");
equips.Add("shield");
equips.Add("gun");
equips.Add("woman");
equips.Add("fruit");
//用剛剛宣告好的Class創建一個儲存數值的物件,並給予數值欄位對應的數值(例如生命設定為100,金錢2500....)
//↓方法1
//Data2 newData = new Data2
//{
// health = 100,
// money = 2500,
// Turing = equips
//};
//↓方法2 兩種方法輸出結果皆相同
Data2 newData = new Data2();
newData.health = 100;
newData.money = 2500;
newData.Turing = equips;
//把剛剛創建好的數值物件轉為Json字串,並用JsonInfo參數儲存(模式A有bool prettyprint)
string jsonInfo = JsonUtility.ToJson(newData, true);
Debug.Log("寫入完成");
//接下來把這個字串寫入指定的檔案位置(下面紅色字請改成自己的路徑《都可以》最後面是檔案名稱)
File.WriteAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55688", jsonInfo);
Debug.Log(jsonInfo);
}
}
來看看輸出結果
Serialize模式B
string jsonInfo = JsonUtility.ToJson(newData);
Debug.Log("寫入完成");
//接下來把這個字串寫入指定的檔案位置(下面紅色字請改成自己的路徑《都可以》最後面是檔案名稱)
File.WriteAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55688", jsonInfo);
Debug.Log(jsonInfo);
來看看輸出結果
接著來看看以JsonUility為主的3種deserialize(反序列化)
Deserialize模式A
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class JsonLoad : MonoBehaviour
{
//宣告一個字串讀取檔案,宣告一個Data物件,來取得字串轉換後的物件
string LoadData;
JsonDemo2.Data MyData;
void Start()
{
//讀取指定路徑的Json檔案並轉成字串
LoadData = File.ReadAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55688");
//把字串轉換成Data物件
JsonDemo2.Data MyData = JsonUtility.FromJson<JsonDemo2.Data>(LoadData);
Debug.Log("Deserialize模式A");
Debug.Log("玩家生命為 " + MyData.health);
Debug.Log("玩家金錢為 " + MyData.money);
Debug.Log("玩家有" + MyData.Turing.Count + "個裝備");
}
}
Deserialize模式B
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class JsonLoad2 : MonoBehaviour
{
//宣告一個字串讀取檔案,宣告一個Data物件,來取得字串轉換後的物件
string LoadData;
JsonDemo2.Data MyData;
void Start()
{
//讀取指定路徑的Json檔案並轉成字串
LoadData = File.ReadAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55688");
//使用public static object FromJson(string json,Type type)來反序列化
MyData = (JsonDemo2.Data)JsonUtility.FromJson(LoadData, typeof(JsonDemo2.Data));
Debug.Log("Deserialize模式B");
Debug.Log("玩家生命為 " + MyData.health);
Debug.Log("玩家金錢為 " + MyData.money);
Debug.Log("玩家有" + MyData.Turing.Count + "個裝備");
}
}
Deserialize模式C
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class JsonLoad3 : MonoBehaviour
{
string LoadData;
JsonDemo2.Data MyData;
void Start()
{
MyData = new JsonDemo2.Data();
deserialize();
}
// 將deserialize()設為一個反序列化用的物件
void deserialize()
{
//讀取指定路徑的Json檔案並轉成字串
LoadData = File.ReadAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55688");
//使用public static void FromJsonOverwrite(string json,object objectToOverwrite)來反序列化
JsonUtility.FromJsonOverwrite(LoadData, MyData);
Debug.Log("Deserialize模式C");
Debug.Log("玩家生命為 " + MyData.health);
Debug.Log("玩家金錢為 " + MyData.money);
Debug.Log("玩家有" + MyData.Turing.Count + "個裝備");
}
}
三種模式的輸出結果
數組序列化
由於當前JsonUility不支援數組序列化,因此需要借助外掛來幫助列化的儲存和讀取,如:SimpleJSON或是JsonHelper。
JsonHelper儲存
using System.Collections.Generic;using UnityEngine;
using System.IO;
using System;
public class JsonArrayDemo : MonoBehaviour
{
//要儲存的物件或是陣列用一個Class去儲存,裡面可以放各類型的資料
//[Serializable]一般除了使陣列可以在inspector中序列化並顯示,在這邊一定要加,沒有的話JsonUility無法序列化數組的Json
[Serializable]
public class ArrayData
{
public float Health;
public int Money;
public string Level;
public List<string> Turing;
}
//Json如包含多個數據對象,例如Health出現了不止一次,由於UnityJsonUtility尚不支持數組,但是可以使用此幫助程序類使數組與JsonUtility一起運作。
//創建一個名為JsonHelper的class。直接複製下面的JsonHelper。
public static class JsonHelper
{
public static T[] FromJson<T>(string jsonArray)
{
jsonArray = WrapArray(jsonArray);
return FromJsonWrapped<T>(jsonArray);
}
public static T[] FromJsonWrapped<T>(string jsonObject)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(jsonObject);
return wrapper.items;
}
private static string WrapArray(string jsonArray)
{
return "{ \"items\": " + jsonArray + "}";
}
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);
}
private class Wrapper<T>
{
public T[] items;
}
}
void Start()
{
//先設置三個不同的陣列等一下給Turing使用
List<string> equips_1 = new List<string>();
equips_1.Add("sword");
equips_1.Add("woman");
equips_1.Add("fruit");
List<string> equips_2 = new List<string>();
equips_2.Add("shield");
equips_2.Add("gun");
equips_2.Add("child");
List<string> equips_3 = new List<string>();
equips_3.Add("sword");
equips_3.Add("cannon");
equips_3.Add("man");
//設定每個數組的數量
ArrayData[] playerInstance = new ArrayData[3];
//設定每個數組的資料
playerInstance[0] = new ArrayData();
playerInstance[0].Health = 100;
playerInstance[0].Money = 2000;
playerInstance[0].Level = "Normal";
playerInstance[0].Turing = equips_1;
playerInstance[1] = new ArrayData();
playerInstance[1].Health = 120;
playerInstance[1].Money = 2000;
playerInstance[1].Level = "Easy";
playerInstance[1].Turing = equips_2;
playerInstance[2] = new ArrayData();
playerInstance[2].Health = 130;
playerInstance[2].Money = 3200;
playerInstance[2].Level = "Hard";
playerInstance[2].Turing = equips_3;
//將Json化的資料存進jsonInfo
string jsonInfo = JsonHelper.ToJson(playerInstance, true);
//輸出至本電腦File.WriteAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55699", jsonInfo);
Debug.Log("寫入完成");
Debug.Log(jsonInfo);
}
}
輸出結果
JsonHelper讀取
using System.IO;
using static JsonArrayDemo;
//繼承JsonArrayDemo中的JsonHelper
public class JsonHelperLoad : MonoBehaviour
{
//宣告一個字串讀取檔案,宣告一個Data物件,來取得字串轉換後的物件
string LoadData;
public ArrayData[] player;
void Start()
{
//讀取指定路徑的Json檔案並轉成字串
LoadData = File.ReadAllText("D:/20193DRowingVR/Mirro3DRowingUnity20194_ThirdPerson/Assets/file55699");
//將數組化ArrayJson反序列化並儲存至pplayer之中
player = JsonHelper.FromJson<ArrayData>(LoadData);
Debug.Log(player[0].Health);
Debug.Log(player[1].Money);
}
}
輸出結果
先這樣吧
其實還有一個JSONSimple的方式,已經搞定讀取的方法但是儲存還在摸索,過個幾天有時間再補上去
過幾天要去面試新的offer,希望可以順利。