一.Protobuf的概念
- 高效轻便的数据存储格式(序列化和反序列化)。
- 与平台和语言无关。
- 在网络通信和数据存储上应用广泛。
二.Protobuf的工作流
环境安装
- 使用
Visual Studio2019
打开Protobuf
源码生成DLL
文件,将DLL
文件导入Unity
。- 下载
Protobuf
编译器。
开始使用
- 编写协议描述文件
*.proto
。- 使用
Protobuf
编译器将协议描述文件*.proto
编译成*.cs
文件,将生成的*.cs
文件导入Unity
。- 编写脚本实现序列化和反序列化。
下载地址
Protocol Buffer
源代码地址:https://github.com/protocolbuffers/protobufProtocol Buffer
编译器地址:https://github.com/protocolbuffers/protobuf/releases/tag/v3.18.1
三.环境安装
1.生成DLL文件并导入Unity
-
下载工程源码后使用
Visual Studio 2019
打开该文件夹中的解决方案。
-
打开解决方案后,在资源管理器中找到
Google.Protobuf
–右键
–生成
。
输出窗口提示生成成功。
- 将工程中的
\csharp\src\Google.Protobuf\bin\Debug\net45
目录下的所有文件导入Unity。
2.下载Protobuf编译器。
- 根据需要下载相应平台的编译器并解压到合适位置。
- 编译器的执行文件目录为
ProtoC\bin\protoc.exe
- 到此为止环境安装完成。
四.开始使用
1.编写协议描述文件。
- 新建文本文档更改后缀为
.proto
,打开文件编辑内容。
文档中关键部分已经注释。更多内容请参考:
官方教程:https://developers.google.com/protocol-buffers/docs/csharptutorial
语法文档:https://developers.google.com/protocol-buffers/docs/proto
//Protobuf版本
syntax="proto2";
//包名,类似C#中的命名空间
package person;
//一条message,类似C#中的类
message OnePerson
{
//[定义声明][数据类型][字段名]=[编号][默认值]
//[定义声明]:required:必填字段;optional:可选字段;repeated:可重复字段
//[数据类型]:字段的类型,与C#稍有不同,更多类型及其说明请参考官网文档.
//[编 号]:唯一标识字段,不可重复,编号1-15使用1个字节进行编码,编号16之后使用两个字节进行编码,推荐将1-15预留给常用的字段,此外编号19000-19999为官方预留,不能使用.
required string name = 1[default = "张三"];
required int64 idNumber = 2[default = 0001];
required genders gender = 3;
optional string profession = 101;[default = "法外狂徒"]
}
//枚举类型
enum genders
{
//该参数为true表示允许字段拥有别名,别名使用相同编号.
option allow_alias = true;
man = 0;
boy = 0;
woman = 1;
girl = 1;
}
2.生成C#脚本文件。
- 打开控制台窗口,定位到编译器可执行文件
protoc.exe
并输入以下命令:
//--proto_path=[输入文件路径]
//--csharp_out=[输出文件路径],其中csharp表示输出文件类型为*.cs文件(C#脚本)。
--proto_path=./ ProtobufTest.proto --csharp_out=./
- 将生成的C#文件导入Unity。
3.使用/测试。
- 编写脚本
ProtobufTest.cs
。
//引入Protobuf命名空间和包名
using Google.Protobuf;
using Person;
public class ProtobufTest : MonoBehaviour
{
void Start()
{
//创建OnePerson对象并初始化
OnePerson onePerson = new OnePerson();
onePerson.Name = "张三";
onePerson.IdNumber = 000001;
onePerson.Gender = genders.Man;
onePerson.Profession = "法外狂徒";
//将onePerson对象转换为字节数组
byte[] dataByte = onePerson.ToByteArray();
//...
//将字节数组转换为OnePerson对象
IMessage message = new OnePerson();
OnePerson mySelf = new OnePerson();
mySelf = (OnePerson)message.Descriptor.Parser.ParseFrom(dataByte);
//打印输出
Debug.Log($"My name is:{mySelf.Name}");
Debug.Log($"My idNumber is:{mySelf.IdNumber}");
Debug.Log($"My gender is:{mySelf.Gender}");
Debug.Log($"My profession is:{mySelf.Profession}");
}
}