一、情景
Unity拥有PlayerPrefs,可以很方便地保存一些简单的数据。但是实际开发中,只使用PlayerPrefs是无法保存很多类型的数据的。所以需要使用C#的序列化方法来存取数据。
二、使用
定义一个存档类,任意类型的数据都可以放在里面,这里只用了两个字符串:
[System.Serializable]
public class Variables
{
public string versionNumber;
public string companyName;
public Variables()
{
versionNumber = "V1.0.0";
playerName = "Mary";
}
}
新建DataManager类。如果想进行文件操作,必须引入System.IO;使用二进制文件保存序列化后的数据,则需要另外一个引用:System.Runtime.Serialization.Formatters.Binary。定义静态存档对象便于调用。
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
public class DataManager : MonoSingleton<DataManager>
{
public static Variables save;
public override void Initialize()
{
LoadData();
}
//写入存档
public void SaveData()
{
FileStream fs = new FileStream(Application.persistentDataPath + "/save.data", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, save);
fs.Close();
}
//读取存档
public void LoadData()
{
if (File.Exists(Application.persistentDataPath + "/save.data"))//如果存在存档文件,则读取它
{
FileStream fs = new FileStream(Application.persistentDataPath + "/save.data", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
save = (Variables)bf.Deserialize(fs);
fs.Close();
}
else//如果不存在存档文件,则使用默认值
{
save = new Variables();
}
}
}
说明:
创建一个文件流,如果目标位置没有同名文件就创建它,如果有则用空文件覆盖它
FileStream fs = new FileStream(“filePath”, FileMode.Create);
创建一个文件流,要求目标位置必须要有文件
FileStream fs = new FileStream(“filePath”, FileMode.Open);
将对象序列化为二进制文件并写入文件流中
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, save);
将二进制文件流反序列化为对象
BinaryFormatter bf = new BinaryFormatter();
save = (Variables)bf.Deserialize(fs);
三、测试
输入名字完成后保存数据,看看关闭后再打开是否保存成功。
验证成功!
四、注意
- 游戏中不要频繁保存数据,会造成卡顿。
- 编辑器清除存档,用默认数据存进存档:
[MenuItem("Tools/ClearSave")]
private static void ClearSave()
{
PlayerPrefs.DeleteAll();
FileStream fs = new FileStream(
Application.persistentDataPath + "/save.data",
FileMode.Create
);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, new Variables());
fs.Close();
}
五、序列化流转化为字符串,使用PlayerPrefs存储
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
private MHMF_LocalDataBase saveInRAM;
public void SaveToLocal()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, saveInRAM);
stream.Position = 0;
byte[] bufferArr = new byte[stream.Length];
stream.Read(bufferArr, 0, bufferArr.Length);
stream.Flush();
stream.Close();
string text = Convert.ToBase64String(bufferArr);
PlayerPrefs.SetString("LocalSaveData", text);
}
public MHMF_LocalDataBase LoadFromLocal()
{
if (PlayerPrefs.HasKey("LocalSaveData"))
{
string strSavedStr = PlayerPrefs.GetString("LocalSaveData", "");
BinaryFormatter bf = new BinaryFormatter();
byte[] bufferArr = Convert.FromBase64String(strSavedStr);
MemoryStream stream = new MemoryStream(bufferArr);
MHMF_LocalDataBase newObj = (MHMF_LocalDataBase)bf.Deserialize(stream);
stream.Flush();
stream.Close();
return newObj;
}
else
{
return null;
}
}