Unity?數(shù)據(jù)存儲(chǔ)和讀取的方法匯總
在 Unity 中實(shí)現(xiàn)對(duì)游戲數(shù)據(jù)存儲(chǔ)和讀取的方法主要有這幾種:
- 使用本地持久化類 PlayerPrefs
- 使用二進(jìn)制的方法序列化和反序列化(Serialize / Deserialize)
- 使用 Json 方法
- 使用 XML 方法
數(shù)據(jù)場(chǎng)景
在 Demo 中分別使用這四種方法實(shí)現(xiàn)面板上數(shù)據(jù)的存儲(chǔ)和讀取
創(chuàng)建一個(gè) Data 腳本用來序列化和反序列化,需要向這個(gè)類中添加需要保存的數(shù)據(jù),最后也是需要從這個(gè)類中讀取保存的數(shù)據(jù)
需要存儲(chǔ)和讀取數(shù)據(jù)的腳本 Data
[System.Serializable] public class Data { // 關(guān)卡/生命值/關(guān)卡得分 public int levels; public int health; public int scores; }
向 Data 中存儲(chǔ)和讀取數(shù)據(jù)的方法
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 數(shù)據(jù)管理 /// </summary> public class DataManager : MonoBehaviour { // 創(chuàng)建 Data 對(duì)象,并添加需要保存的數(shù)據(jù) private Data GetGameData() { Data data = new Data(); data.levels = CanvasManager.Instance.levels; data.health = CanvasManager.Instance.health; data.scores = CanvasManager.Instance.scores; return data; } // 向游戲中加載 Data 中保存的數(shù)據(jù) private void SetGameData(Data data) { CanvasManager.Instance.levels = data.levels; CanvasManager.Instance.health = data.health; CanvasManager.Instance.scores = data.scores; CanvasManager.Instance.DataUpdate(); } }
PlayerPrefs
Playerprefs 是 Unity 提供的一個(gè)用于本地?cái)?shù)據(jù)持久化保存和讀取的類
原理就是利用 Key - Value 的方式將數(shù)據(jù)保存到本地(跟字典類似),然后通過代碼實(shí)現(xiàn)數(shù)據(jù)保存、讀取和更新的操作
* PlayerPrefs 只能保存 int 型、float 型和 string 型的數(shù)據(jù),對(duì)于 bool 類型可以用 1/0 代替 真/假,實(shí)現(xiàn)保存的目的 *
// 數(shù)據(jù)存儲(chǔ):PlayerPrefs private void SaveByPlayerPrefs() { PlayerPrefs.SetInt("Levels", CanvasManager.Instance.levels); PlayerPrefs.SetInt("Health", CanvasManager.Instance.health); PlayerPrefs.SetInt("Scores", CanvasManager.Instance.scores); PlayerPrefs.Save(); } // 數(shù)據(jù)讀?。篜layerPrefs private void LoadByPlayerPrefs() { if (PlayerPrefs.HasKey("Levels") && PlayerPrefs.HasKey("Health") && PlayerPrefs.HasKey("Scores")) { CanvasManager.Instance.levels = PlayerPrefs.GetInt("Levels"); CanvasManager.Instance.health = PlayerPrefs.GetInt("Health"); CanvasManager.Instance.scores = PlayerPrefs.GetInt("Scores"); CanvasManager.Instance.DataUpdate(); } else Debug.Log("- 未找到相應(yīng)數(shù)據(jù) -"); }
通過 PlayerPrefs 中的 SetInt() 將面板上的數(shù)據(jù)通過鍵值對(duì)的形式進(jìn)行存儲(chǔ);然后通過 GetInt() 去讀取保存下來的值
面板上保存數(shù)據(jù)和加載數(shù)據(jù)按鈕執(zhí)行的方法
// 保存游戲數(shù)據(jù) public void SaveGameData() { SaveByPlayerPrefs(); //通過 PlayerPrefs 方式保存 } // 加載游戲數(shù)據(jù) public void LoadGameData() { LoadByPlayerPrefs(); //通過 PlayerPrefs 方式讀取 }
序列化與反序列化
保存的時(shí)候:
首先創(chuàng)建二進(jìn)制格式化程序,然后創(chuàng)建文件流,通過格式化程序?qū)?Data 進(jìn)行序列化并保存到本地
讀取的時(shí)候:
先創(chuàng)建二進(jìn)制格式化程序,然后創(chuàng)建文件流,通過格式化程序?qū)?Data 反序列化出來,然后重新設(shè)置數(shù)據(jù)
// 數(shù)據(jù)存儲(chǔ):二進(jìn)制方法 private void SaveByBin() { try { Data data = GetGameData(); // 創(chuàng)建二進(jìn)制格式化程序 BinaryFormatter bf = new BinaryFormatter(); using (FileStream fs = File.Create(Application.dataPath + "/SaveFiles" + "/ByBin.Txt")) { // 將 data 序列化 bf.Serialize(fs, data); } } catch (System.Exception e) { Debug.Log(e.Message); } } // 數(shù)據(jù)讀?。憾M(jìn)制方法 private void LoadByBin() { try { BinaryFormatter bf = new BinaryFormatter(); using (FileStream fs = File.Open(Application.dataPath + "/SaveFiles" + "/ByBin.Txt", FileMode.Open)) { // 將 data 反序列化 Data data = (Data)bf.Deserialize(fs); SetGameData(data); } } catch (System.Exception e) { Debug.Log(e.Message); } }
* 文件流創(chuàng)建使用后需要及時(shí)關(guān)閉,即 fs.Close() *
在這里使用 using 指令的話就會(huì)自動(dòng)關(guān)閉,省略了一步關(guān)閉的步驟
面板上保存數(shù)據(jù)和加載數(shù)據(jù)按鈕執(zhí)行的方法
// 保存游戲數(shù)據(jù) public void SaveGameData() { //SaveByPlayerPrefs(); //通過 PlayerPrefs 方式保存 SaveByBin(); //通過二進(jìn)制方式 } // 加載游戲數(shù)據(jù) public void LoadGameData() { //LoadByPlayerPrefs(); //通過 PlayerPrefs 方式讀取 LoadByBin(); //通過二進(jìn)制方式讀取 }
保存成功后可以在 SaveFiles 文件夾中看到一個(gè) ByBin.txt 文件
Json
json 是一種輕量級(jí)的數(shù)據(jù)交換格式,使用 Json 在 Unity 中實(shí)現(xiàn)數(shù)據(jù)的存儲(chǔ)和讀取是非常方便的
* 需要導(dǎo)入使用 Json 所需要的插件 *
// 數(shù)據(jù)存儲(chǔ):Json private void SaveByJson() { Data data = GetGameData(); string dataPath = Application.dataPath + "/SaveFiles" + "/ByJson.json"; // 利用 JsonMapper 將 data 轉(zhuǎn)換成字符串 string dataStr = JsonMapper.ToJson(data); // 創(chuàng)建寫入流寫入數(shù)據(jù) StreamWriter sw = new StreamWriter(dataPath); sw.Write(dataStr); // 關(guān)閉流 sw.Close(); } // 數(shù)據(jù)讀?。篔son private void LoadByJson() { string dataPath = Application.dataPath + "/SaveFiles" + "/ByJson.json"; // 判斷路徑文件 if (File.Exists(dataPath)) { // 創(chuàng)建讀取流讀取數(shù)據(jù) StreamReader sr = new StreamReader(dataPath); string jsonStr = sr.ReadToEnd(); sr.Close(); // 使用 JsonMapper 將得到的 jsonStr 轉(zhuǎn)換為 data 對(duì)象 Data data = JsonMapper.ToObject<Data>(jsonStr); SetGameData(data); } else Debug.Log("- 未找到相應(yīng)文件 -"); }
面板上保存數(shù)據(jù)和加載數(shù)據(jù)按鈕執(zhí)行的方法
// 保存游戲數(shù)據(jù) public void SaveGameData() { //SaveByPlayerPrefs(); //通過 PlayerPrefs 方式保存 //SaveByBin(); //通過二進(jìn)制方式存儲(chǔ) SaveByJson(); // 通過 Json 方式存儲(chǔ) } // 加載游戲數(shù)據(jù) public void LoadGameData() { //LoadByPlayerPrefs(); //通過 PlayerPrefs 方式讀取 //LoadByBin(); //通過二進(jìn)制方式讀取 LoadByJson(); //通過 Json 方式讀取 }
保存成功后可以在 SaveFiles 文件夾中看到一個(gè) json 文件
相較于上一種方法,Json 數(shù)據(jù)的可讀性要好很多
XML
XML 相較于 Json 來說可讀性比較好,但文件龐大,格式復(fù)雜,沒有 Json 簡(jiǎn)約
// 數(shù)據(jù)存儲(chǔ):Xml private void SaveByXml() { Data data = GetGameDate(); string dataPath = Application.dataPath + "/SaveFiles" + "/ByXml.txt"; // 創(chuàng)建 Xml 文檔 XmlDocument xmlDoc = new XmlDocument(); // 創(chuàng)建根節(jié)點(diǎn)并設(shè)置名稱 XmlElement root = xmlDoc.CreateElement("SaveByXml"); root.SetAttribute("name", "savefile"); // 創(chuàng)建其他節(jié)點(diǎn)并設(shè)置值 XmlElement levels = xmlDoc.CreateElement("levels"); levels.InnerText = data.levels.ToString(); XmlElement health = xmlDoc.CreateElement("health"); health.InnerText = data.health.ToString(); XmlElement scores = xmlDoc.CreateElement("scores"); scores.InnerText = data.scores.ToString(); // 將子節(jié)點(diǎn)加入根節(jié)點(diǎn),并將根節(jié)點(diǎn)加入 Xml 文檔 root.AppendChild(levels); root.AppendChild(health); root.AppendChild(scores); xmlDoc.AppendChild(root); xmlDoc.Save(dataPath); } // 數(shù)據(jù)讀取:Xml private void LoadByXml() { string dataPath = Application.dataPath + "/SaveFiles" + "/ByXml.txt"; if (File.Exists(dataPath)) { Data data = new Data(); XmlDocument xmlDoc = new XmlDocument(); // 加載指定路徑的 Xml 文檔 xmlDoc.Load(dataPath); // 通過名字得到相對(duì)應(yīng)的值 XmlNodeList levels = xmlDoc.GetElementsByTagName("levels"); data.levels = int.Parse(levels[0].InnerText); XmlNodeList health = xmlDoc.GetElementsByTagName("health"); data.health = int.Parse(health[0].InnerText); XmlNodeList scores = xmlDoc.GetElementsByTagName("scores"); data.scores = int.Parse(scores[0].InnerText); SetGameDate(data); } else Debug.Log("- 未找到相應(yīng)文件 -"); }
面板上保存數(shù)據(jù)和加載數(shù)據(jù)按鈕執(zhí)行的方法
// 保存游戲數(shù)據(jù) public void SaveGameData() { //SaveByPlayerPrefs(); //通過 PlayerPrefs 方式保存 //SaveByBin(); //通過二進(jìn)制方式存儲(chǔ) //SaveByJson(); //通過 Json 方式存儲(chǔ) SaveByXml(); //通過 Xml 方式存儲(chǔ) } // 加載游戲數(shù)據(jù) public void LoadGameData() { //LoadByPlayerPrefs(); //通過 PlayerPrefs 方式讀取 //LoadByBin(); //通過二進(jìn)制方式讀取 //LoadByJson(); //通過 Json 方式讀取 LoadByXml(); //通過 Xml 方式讀取 }
保存成功后可以在 SaveFiles 文件夾中看到一個(gè) txt 文件
以上就是使用這四種方法在 Unity 中實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)和讀取方法的案例內(nèi)容
到此這篇關(guān)于Unity 數(shù)據(jù)存儲(chǔ)和讀取的方法的文章就介紹到這了,更多相關(guān)Unity 數(shù)據(jù)存儲(chǔ)和讀取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Unity計(jì)時(shí)器功能實(shí)現(xiàn)示例
計(jì)時(shí)器在很多地方都可以使用,本文主要介紹了Unity計(jì)時(shí)器功能實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10C#實(shí)現(xiàn)連接電子秤串口自動(dòng)稱重
這篇文章介紹了C#實(shí)現(xiàn)連接電子秤串口自動(dòng)稱重的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04C#中IEnumerable接口介紹并實(shí)現(xiàn)自定義集合
這篇文章介紹了C#中IEnumerable接口并實(shí)現(xiàn)自定義集合,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04C#實(shí)現(xiàn)漢字轉(zhuǎn)拼音或轉(zhuǎn)拼音首字母的方法
這篇文章主要介紹了C#實(shí)現(xiàn)漢字轉(zhuǎn)拼音或轉(zhuǎn)拼音首字母的方法,涉及C#操作數(shù)組、遍歷及正則匹配的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07C#使用zxing/zbar/thoughtworkQRcode解析二維碼的示例代碼
zxing是谷歌開源的二維碼庫,zbar,thoughtworkQRcode也是開源的,三者之間比較各有優(yōu)劣,本文將通過一個(gè)案例demo源碼,帶來認(rèn)識(shí)學(xué)習(xí)下這三者的實(shí)際解碼效果,感興趣的可以了解一下2023-07-07