Unity?數(shù)據(jù)存儲和讀取的方法匯總
在 Unity 中實(shí)現(xiàn)對游戲數(shù)據(jù)存儲和讀取的方法主要有這幾種:
- 使用本地持久化類 PlayerPrefs
- 使用二進(jìn)制的方法序列化和反序列化(Serialize / Deserialize)
- 使用 Json 方法
- 使用 XML 方法
數(shù)據(jù)場景
在 Demo 中分別使用這四種方法實(shí)現(xiàn)面板上數(shù)據(jù)的存儲和讀取

創(chuàng)建一個(gè) Data 腳本用來序列化和反序列化,需要向這個(gè)類中添加需要保存的數(shù)據(jù),最后也是需要從這個(gè)類中讀取保存的數(shù)據(jù)
需要存儲和讀取數(shù)據(jù)的腳本 Data
[System.Serializable]
public class Data
{
// 關(guān)卡/生命值/關(guān)卡得分
public int levels;
public int health;
public int scores;
}向 Data 中存儲和讀取數(shù)據(jù)的方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 數(shù)據(jù)管理
/// </summary>
public class DataManager : MonoBehaviour
{
// 創(chuàng)建 Data 對象,并添加需要保存的數(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ù),對于 bool 類型可以用 1/0 代替 真/假,實(shí)現(xiàn)保存的目的 *
// 數(shù)據(jù)存儲: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ù)通過鍵值對的形式進(jìn)行存儲;然后通過 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ù)存儲:二進(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 指令的話就會自動(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 是一種輕量級的數(shù)據(jù)交換格式,使用 Json 在 Unity 中實(shí)現(xiàn)數(shù)據(jù)的存儲和讀取是非常方便的
* 需要導(dǎo)入使用 Json 所需要的插件 *
// 數(shù)據(jù)存儲: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ù)讀取:Json
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 對象
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)制方式存儲
SaveByJson(); // 通過 Json 方式存儲
}
// 加載游戲數(shù)據(jù)
public void LoadGameData()
{
//LoadByPlayerPrefs(); //通過 PlayerPrefs 方式讀取
//LoadByBin(); //通過二進(jìn)制方式讀取
LoadByJson(); //通過 Json 方式讀取
}保存成功后可以在 SaveFiles 文件夾中看到一個(gè) json 文件

相較于上一種方法,Json 數(shù)據(jù)的可讀性要好很多
XML
XML 相較于 Json 來說可讀性比較好,但文件龐大,格式復(fù)雜,沒有 Json 簡約
// 數(shù)據(jù)存儲: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);
// 通過名字得到相對應(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)制方式存儲
//SaveByJson(); //通過 Json 方式存儲
SaveByXml(); //通過 Xml 方式存儲
}
// 加載游戲數(shù)據(jù)
public void LoadGameData()
{
//LoadByPlayerPrefs(); //通過 PlayerPrefs 方式讀取
//LoadByBin(); //通過二進(jìn)制方式讀取
//LoadByJson(); //通過 Json 方式讀取
LoadByXml(); //通過 Xml 方式讀取
}保存成功后可以在 SaveFiles 文件夾中看到一個(gè) txt 文件

以上就是使用這四種方法在 Unity 中實(shí)現(xiàn)數(shù)據(jù)存儲和讀取方法的案例內(nèi)容
到此這篇關(guān)于Unity 數(shù)據(jù)存儲和讀取的方法的文章就介紹到這了,更多相關(guān)Unity 數(shù)據(jù)存儲和讀取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# 使用匿名函數(shù)解決EventHandler參數(shù)傳遞的難題
C#動(dòng)態(tài)生成PictureBox并綁定右鍵菜單,實(shí)現(xiàn)刪除圖片2009-05-05
關(guān)于C#轉(zhuǎn)換二進(jìn)制所引起的一些思考
這篇文章主要給大家介紹了關(guān)于C#轉(zhuǎn)換二進(jìn)制所引起的一些思考,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
C#函數(shù)式編程中的標(biāo)準(zhǔn)高階函數(shù)詳解
這篇文章主要介紹了C#函數(shù)式編程中的標(biāo)準(zhǔn)高階函數(shù)詳解,本文講解了何為高階函數(shù)、Map、 Filter、Fold等內(nèi)容,需要的朋友可以參考下2015-01-01

