Unity3D json 存档读档功能。
序列化
游戏存档通常是把存在于内存中的对象,通过序列化,把对象中的数据存储到文件中,实现数据的持久化。
游戏读档则是把文件中的数据,通过反序列化,重新生成内存中的对象。
存档的格式,一般使用 json 存储,也可以使用二进制、XML等。
存档
首先,需要安装一个 json 库,在 Package Manager 窗口中,搜索 Newtonsoft Json 进行安装。
也可以使用其他 json 库,Newtonsoft Json 的优点是可以很好地序列化字典。
接着,创建一个 GameData 类,标记为可序列化。
1 2 3 4 5 6 7 8 9 10 11 12
| using System;
[Serializable] public class GameData { public int playerID;
public GameData() { playerID = 100001; } }
|
然后创建一个 DataManager 类,用来管理存档。
这里的 SavePath 添加了平台宏定义,如果是在 unity editor 中运行,就直接存储到 Assets 文件夹中,其他平台则是存储到可读写的数据目录中。
通过调用 JsonConvert.SerializeObject
方法,把 gameData 序列化成 json 字符串,再使用 StreamWriter
写入本地文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| using System.IO; using UnityEngine; using Newtonsoft.Json;
public class DataManager : MonoBehaviour { public GameData gameData;
string SavePath { get { #if UNITY_EDITOR return Application.dataPath + "/SaveData.json"; #else return Application.persistentDataPath + "/SaveData.json"; #endif } }
void Start() { Save(); }
public void Save() { string json = JsonConvert.SerializeObject(gameData); StreamWriter sw = new StreamWriter(SavePath); sw.Write(json); sw.Close(); } }
|
运行游戏之后,停止运行,刷新工程资源目录,可以看到 Assets 文件夹下多出了一个 SaveData.json 文件。
json 的内容如下:
读档
读档的时候,要先判断本地是否有存档文件,再进行文件的读取和反序列化,还原 gameData 数据对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class DataManager : MonoBehaviour { public void Load() { if (File.Exists(SavePath)) { StreamReader sr = new StreamReader(SavePath); string json = sr.ReadToEnd(); sr.Close(); gameData = JsonConvert.DeserializeObject<GameData>(json); } } }
|
在游戏开始时,先读档,再修改数据对象,再次存档。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class DataManager : MonoBehaviour { void Start() { Load(); gameData.playerID = 100002; Save(); } }
|
可以看到,json 的内容改变了。
数据对象扩展
目前 GameData 中只有一个 playerID,实际上可以再定义更多的数据类,统一放到 GameData 中作为成员字段。
例如,定义一个 DataPlayer 类,保存玩家的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class DataPlayer { public int playerID; public string playerName; public int health;
public DataPlayer() { playerID = 100001; playerName = "Player"; health = 100; } }
|
然后把 DataPlayer 放到 GameData 中,在构造函数中要记得实例化对象。
1 2 3 4 5 6 7 8 9 10 11 12
| using System;
[Serializable] public class GameData { public DataPlayer dataPlayer;
public GameData() { dataPlayer = new DataPlayer(); } }
|
游戏开始时,修改一下玩家名字,再存档。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class DataManager : MonoBehaviour { void Start() { Load(); gameData.dataPlayer.playerName = "起个名字很难"; Save(); } }
|
此时,json 的内容如下:
1 2 3 4 5 6 7
| { "dataPlayer": { "playerID": 100001, "playerName": "起个名字很难", "health": 100 } }
|