在Unity3D使用JSON製作存檔
前言
最近搜尋到Unity3D已經內建支援JSON,想到以前製作存檔是透過PlayerPrefs來儲存相當不好用。想想自己太久沒用Unity3D,該跟上新的製作存檔方式了。內容
以前用PlayerPrefs製作存檔不需考慮儲存的位置,因為Unity3D會規劃怎麼儲存,新的做法如下圖存檔的寫入與讀取 |
Data是如何轉換成JSON的呢?看以下範例
public class PlayerData { public int intData = 0; public float floatData = 3.14159f; public PlayerData ptrData = null;//This value will be ignored in json public string stringData = "I'm a string"; public Vector3 vec3Data = Vector3.zero; public Matrix4x4 mat44Data = Matrix4x4.identity; public List<int> intListData = new List<int>(); public Dictionary<int, int> intDictData = new Dictionary<int, int>();//This value will be ignored in json public Dictionary<string, int> strDictData = new Dictionary<string, int>(); //This value will be ignored in json } // PlayerData data = new PlayerData(); //Convert to json string jsonStr = JsonUtility.ToJson(data); // //Convert to data PlayerData loadData = JsonUtility.FromJson<PlayerData>(jsonStr);
先把要儲存的資料包成class,不過要注意並不是所有的都可以儲存,會被儲存的資料一定是"public",常見的int、float...等有支援,要注意的是不支援的資料型態,不支援的資料型態是"Reference"與"Dictionary",轉成JSON和轉回資料的部分相當簡單就不多說了。
接著來看看JSON寫入與讀取的部分,這個部分個人認為使用Binary的方式較為理想(個人比較熟),先看以下範例
using System.IO; using System.Text; // const string fileName = "playerData.dat"; string filePath = Application.persistentDataPath + "/" + fileName; string jsonStr = JsonUtility.ToJson(data); // // Save try { File.WriteAllBytes(filePath, Encoding.UTF8.GetBytes(jsonStr)); Debug.Log("Save OK!"); } catch (System.Exception e) { Debug.Log("Save failed!"); } // Load try { string loadData = Encoding.UTF8.GetString(File.ReadAllBytes(filePath) ); PlayerData myData = JsonUtility.FromJson<PlayerData>(loadData); Debug.Log("Load OK!"); } catch (System.Exception e) { Debug.Log("Load failed!"); }
寫入的部分要透過"Encodin.UTF8.GetBytes()",而讀取的時候透過"Encodin.UTF8.GetString()"來還原,這個步驟可以讓string的資料可以支援unicode,檔案的開啟與讀取和以前是一樣的。完整的範例如下
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using System.Text; public class PlayerData { public int intData = 0; public float floatData = 3.14159f; public PlayerData ptrData = null;//This value will be ignored in json public string stringData = "I'm a string.許"; public Vector3 vec3Data = Vector3.zero; public Matrix4x4 mat44Data = Matrix4x4.identity; public List<int> intListData = new List<int>(); public Dictionary<int, int> intDictData = new Dictionary<int, int>();//This value will be ignored in json public Dictionary<string, int> strDictData = new Dictionary<string, int>(); //This value will be ignored in json } public class SaveLoadTest : MonoBehaviour { // Start is called before the first frame update void Awake() { } void Start() { const string fileName = "playerData.dat"; string filePath = Application.persistentDataPath + "/" + fileName; PlayerData data = new PlayerData(); data.intListData.Add(9527); data.intListData.Add(2266); data.intDictData.Add(1, 1234); data.intDictData.Add(1024, 7788); data.strDictData.Add("abc", 123); data.strDictData.Add("abc123", 789); // string jsonStr = JsonUtility.ToJson(data); Debug.Log(jsonStr); // // Save try { File.WriteAllBytes(filePath, Encoding.UTF8.GetBytes(jsonStr)); Debug.Log("Save OK!"); } catch (System.Exception e) { Debug.Log("Save failed!"); } // Load try { string loadData = Encoding.UTF8.GetString(File.ReadAllBytes(filePath) ); Debug.Log("loadData:"+loadData); PlayerData myData = JsonUtility.FromJson<PlayerData>(loadData); Debug.Log("Load OK!"); } catch (System.Exception e) { Debug.Log("Load failed!"); } } // Update is called once per frame void Update() { } }
參考資料
Introduction to Saving and LoadingUnity 遊戲存檔機制淺談,從序列化 (Serialization) 到儲存裝置 (Storage)
沒有留言:
張貼留言