關(guān)鍵詞:
- Unity3D
- ProtoBuf
- 序列化
開(kāi)發(fā)環(huán)境:
- 引擎版本: Unity3D 5.4.1f1 Personal
簡(jiǎn)述
前段時(shí)間在看一個(gè)unity3d教程,在教程項(xiàng)目中用到了ProtoBuf,然后我在編寫(xiě)完代碼之后運(yùn)行時(shí)報(bào)錯(cuò)了,檢測(cè)若干遍代碼邏輯,最后發(fā)現(xiàn)是忘了寫(xiě)[ProtoContract],所以記錄一下使用方法和問(wèn)題。
簡(jiǎn)單使用方法
將ProtoBuf倒入到項(xiàng)目中
一般來(lái)說(shuō),有兩種方式可以將ProtoBuf倒入到自己的項(xiàng)目中:
- 從Github下載ProtoBuf的源碼放入自己的工程。
- 將編譯好的dll庫(kù)放入自己的工程。
這里我從網(wǎng)上下載了一個(gè)protobuf-net.dll文件,直接放到了我的unity3d項(xiàng)目下。

u3d項(xiàng)目下的protobuf-net.dll
一個(gè)使用ProtoBuf的示例
using System;
//需要用到MemoryStream
using System.IO;
using UnityEngine;
//引入ProtoBuf命名空間
using ProtoBuf;
/// <summary>
/// 測(cè)試類
/// </summary>
public class TestProtobuf : MonoBehaviour {
/// <summary>
/// 用于測(cè)試的數(shù)據(jù)類
/// </summary>
[ProtoContract] //聲明這個(gè)類能被序列化
public class UserData
{
//聲明每一個(gè)需要被序列化的成員,編號(hào)從1開(kāi)始
[ProtoMember(1)]
public int id;
[ProtoMember(2)]
public string name;
[ProtoMember(3)]
public int level;
}
//測(cè)試代碼
void Start()
{
//將要被序列化的UserData示例
UserData user1 = new UserData ();
user1.id = 1;
user1.name = "User1";
user1.level = 10;
//打印user1
Debug.Log (string.Format ("user1-> id:{0}, name:{1}, level:{2}", user1.id, user1.name, user1.level));
//序列化
byte[] buff = null;
using (MemoryStream ms = new MemoryStream ()) {
Serializer.Serialize<UserData> (ms, user1);
ms.Position = 0;
int length = (int)ms.Length;
buff = new byte[length];
ms.Read (buff, 0, length);
}
//輸出字節(jié)數(shù)組
Debug.Log (string.Format("Serialized data-> {0}", BitConverter.ToString(buff)));
//反序列化
UserData user2 = default(UserData);
using (MemoryStream ms = new MemoryStream (buff)) {
user2 = Serializer.Deserialize<UserData> (ms);
}
//打印反序列化生成的user2
Debug.Log (string.Format ("user2-> id:{0}, name:{1}, level:{2}", user2.id, user2.name, user2.level));
}
}
使用ProtoBuf對(duì)一個(gè)數(shù)據(jù)類進(jìn)行序列化和反序列化的過(guò)程如上代碼。
我將這段代碼保存為TestProtobuf.cs文件,并添加到我的Camera對(duì)象上,運(yùn)行結(jié)果如圖:

運(yùn)行結(jié)果
總結(jié)
對(duì)于ProtoBuf的用途已經(jīng)有太多博客去進(jìn)行描述,對(duì)于ProtoBuf我目前也沒(méi)有特別的使用技巧,在此就不贅述了。
以下補(bǔ)充以下需要注意的問(wèn)題:
- 對(duì)需要序列化的類,兩種聲明([ProtoContract],[ProtoMember(編號(hào))])一定要記得添加。如果未對(duì)類添加[ProtoContract]聲明,在進(jìn)行序列化時(shí)會(huì)報(bào)錯(cuò),提示找不到對(duì)應(yīng)的類。如果未對(duì)成員添加[ProtoMember(編號(hào))]聲明,則該成員不會(huì)被序列化,其他成員不受影響。如果[ProtoMember(編號(hào))]聲明的編號(hào)使用了0,運(yùn)行時(shí)會(huì)報(bào)錯(cuò)參數(shù)超出范圍,如果在一個(gè)類中使用了重復(fù)的編號(hào),運(yùn)行時(shí)會(huì)報(bào)錯(cuò)提示參數(shù)重復(fù)。
- 在實(shí)際項(xiàng)目中使用ProtoBuf時(shí),盡量將序列化和反序列化的邏輯使用泛型封裝起來(lái)。