什么是序列化,反序列化焦除?
- 序列化就是把數(shù)據(jù)對(duì)象轉(zhuǎn)換成二進(jìn)制流保存為本地文件的過程激况。
- 反序列化就是把儲(chǔ)存有數(shù)據(jù)信息的二進(jìn)制文件還原成數(shù)據(jù)對(duì)象的過程。
序列化的意義
- 以某種儲(chǔ)存形式(二進(jìn)制/XML膘魄,今天只講二進(jìn)制方法)使自定義對(duì)象持久化
- 方便將對(duì)象從一個(gè)地方移動(dòng)到另一個(gè)地方(轉(zhuǎn)移文件再反序列化讀任谥稹)
- 使游戲數(shù)據(jù)不容易被直接篡改
序列化在unity中的注意點(diǎn)
不可以直接序列化unity特有的數(shù)據(jù)類型(例如Vector3, Quaternion),必須要轉(zhuǎn)換一下(例子在下)。不然會(huì)報(bào)錯(cuò):"SerializationException: Type UnityEngine.XXX is not marked as Serializable."
舉個(gè)例子
using System;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;//實(shí)現(xiàn)二進(jìn)制串行化必需的庫(kù)
using System.IO; //實(shí)現(xiàn)文件流所必需的庫(kù)
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()
{
//首先實(shí)例化一個(gè)二進(jìn)制串行化對(duì)象创葡,用于將數(shù)據(jù)串行化
BinaryFormatter bf = new BinaryFormatter();
//然后實(shí)例化一個(gè)文件流用于在目錄中創(chuàng)建 plyaerInfo.dat 文件(文件名自定義)
//persistentDataPath將指向設(shè)備上的公用目錄,App的每次更新都將不會(huì)刪除此位置的文件
FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.dat");
//將實(shí)時(shí)信息儲(chǔ)存到信息類中浙踢,等待序列化。
PlayerData data = new PlayerData();
data.health = currentHealth;
data.sv3 = transform.position;
//序列化儲(chǔ)存
bf.Serialize(file, data); //將data序列化為file文件(即playerInfo.dat)儲(chǔ)存
file.Close(); //關(guān)閉流操作
}
private void Load()
{
//首先確定有儲(chǔ)存信息
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] //可序列化標(biāo)志
class PlayerData
{
public float health;
public SerializableVector3 sv3;
}
//在Vector3 和 SerializableVector3之間自動(dòng)轉(zhuǎn)換
[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;
}
// 以字符串形式返回,方便調(diào)試查看
public override string ToString()
{
return String.Format("[{0}, {1}, {2}]", x, y, z);
}
// 隱式轉(zhuǎn)換:將SerializableVector3 轉(zhuǎn)換成 Vector3
public static implicit operator Vector3(SerializableVector3 rValue)
{
return new Vector3(rValue.x, rValue.y, rValue.z);
}
// 隱式轉(zhuǎn)換:將Vector3 轉(zhuǎn)成 SerializableVector3
public static implicit operator SerializableVector3(Vector3 rValue)
{
return new SerializableVector3(rValue.x, rValue.y, rValue.z);
}
}
捷徑
有一個(gè)可以序列化.net和unity數(shù)據(jù)結(jié)構(gòu)的unity插件——RunTime Serialization