在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)


