什么是序列化,反序列化?
- 序列化就是把数据对象转换成二进制流保存为本地文件的过程。
- 反序列化就是把储存有数据信息的二进制文件还原成数据对象的过程。
序列化的意义
- 以某种储存形式(二进制/XML,今天只讲二进制方法)使自定义对象持久化
- 方便将对象从一个地方移动到另一个地方(转移文件再反序列化读取)
- 使游戏数据不容易被直接篡改
序列化在unity中的注意点
不可以直接序列化unity特有的数据类型(例如Vector3, Quaternion),必须要转换一下(例子在下)。不然会报错:"SerializationException: Type UnityEngine.XXX is not marked as Serializable."
举个例子
using System;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;//实现二进制串行化必需的库
using System.IO; //实现文件流所必需的库
public class GoBack : MonoBehaviour
{
public float currentHealth = 0;
private void Awake()
{
Load();
}
private void FixedUpdate()
{
currentHealth += Time.deltaTime;
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 100, 30), "Save"))
Save();
if (GUI.Button(new Rect(10, 40, 100, 30), "Load"))
Load();
GUI.Label(new Rect(10,70,100,30),currentHealth.ToString());
}
private void Save()
{
//首先实例化一个二进制串行化对象,用于将数据串行化
BinaryFormatter bf = new BinaryFormatter();
//然后实例化一个文件流用于在目录中创建 plyaerInfo.dat 文件(文件名自定义)
//persistentDataPath将指向设备上的公用目录,App的每次更新都将不会删除此位置的文件
FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.dat");
//将实时信息储存到信息类中,等待序列化。
PlayerData data = new PlayerData();
data.health = currentHealth;
data.sv3 = transform.position;
//序列化储存
bf.Serialize(file, data); //将data序列化为file文件(即playerInfo.dat)储存
file.Close(); //关闭流操作
}
private void Load()
{
//首先确定有储存信息
if (File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
{
//将文件反序列化
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
PlayerData data = bf.Deserialize(file) as PlayerData;
file.Close();
currentHealth = data.health;
transform.position = data.sv3;
}
}
}
[Serializable] //可序列化标志
class PlayerData
{
public float health;
public SerializableVector3 sv3;
}
//在Vector3 和 SerializableVector3之间自动转换
[Serializable]
public struct SerializableVector3
{
public float x;
public float y;
public float z;
public SerializableVector3(float rX, float rY, float rZ)
{
x = rX;
y = rY;
z = rZ;
}
// 以字符串形式返回,方便调试查看
public override string ToString()
{
return String.Format("[{0}, {1}, {2}]", x, y, z);
}
// 隐式转换:将SerializableVector3 转换成 Vector3
public static implicit operator Vector3(SerializableVector3 rValue)
{
return new Vector3(rValue.x, rValue.y, rValue.z);
}
// 隐式转换:将Vector3 转成 SerializableVector3
public static implicit operator SerializableVector3(Vector3 rValue)
{
return new SerializableVector3(rValue.x, rValue.y, rValue.z);
}
}
捷径
有一个可以序列化.net和unity数据结构的unity插件——RunTime Serialization