目录

1.介绍

1.1 什么是Protobuf

1.2 Protobuf和其他数据序列化方案对比

2.下载Protobuf

2.1 方案一 使用VS的Nuget包管理器进行安装(推荐)

2.1.1安装Protobuff包

2.1.2拷贝.dll文件

2.2 方案二 从Github下载并自己生成.dll

2.2.1 下载Probuff

2.2.2 VS打开解决方案

2.2.3 安装.NET SDK

2.2.4 生成.dll文件

3.使用Protoc工具生成.cs文件

3.1 下载Protoc

3.2 进入Bin文件夹目录

3.3 写一个.proto例子

3.4 使用proto.exe将.proto转换成可以在C#中使用的.cs文件

4.在Unity中使用Protobuff

4.1 将生成的.cs文件导入我们的Unity项目中

4.2 建一个Proto工具类,用来进行对我们的数据进行序列化和反序列化

4.3 写一个测试类

简单小结


1.介绍

1.1 什么是Protobuf

Protobuf,全程“Protocol Buffers”,是Google公司开发的一种对数据进行序列化/反序列化的技术。目前比较广泛地被用在网络传输通信中,作为一种数据交换格式进行使用

1.2 Protobuf和其他数据序列化方案对比

序列化文件大小

可读性

跨语言

跨平台

性能

易用性

适用场景

XML


高,包含所有层级结构和信息

支持

支持


复杂,像Excel一样逐节点查询

配置文件、定义协议等

Json

较小

较高,所有数据以键值对形式储存

支持

支持

较高

简单

轻量级的数据存储和网络传输通信

Protobuf


低,不包含字段名等信息,且需要适用专门的工具进行反序列化

支持

支持


较复杂,需要自己定义Proto数据结构,但序列化反序列化过程简单

高性能,低带宽的网络传输通信

二进制

极小

低,全是0和1二进制字节

不支持

不支持

极高

简单

有加密需求的大规模网络传输通信,数据存储等

2.下载Protobuf

Protobuf的Github链接

选择一个版本,笔者这边以V3.23.3版本举例

在线 protobuff转java类_序列化

2.1 方案一 使用VS的Nuget包管理器进行安装(推荐)

2.1.1安装Protobuff包

 点击VS顶部工具栏→工具→NuGet包管理器→管理解决方案的NuGet程序包

在线 protobuff转java类_序列化_02

点击浏览,搜索proto,点击Google.Protobuff,选中Assembly-Csharp程序集,选择跟我们合适的版本号进行安装

在线 protobuff转java类_网络_03

2.1.2拷贝.dll文件

安装成功后会在我们项目的Package文件夹下生成这几个文件夹,我们进入选中的这几个文件夹,选择lib→.netstandard2.0各自的.dll文件,不然在代码中无法识别API

在线 protobuff转java类_反序列化_04

比如System.Memory中就是这个

在线 protobuff转java类_反序列化_05

在Unity项目Plugins目录导入上面这四个.dll文件,就可以正常使用了,生成这个.dll文件只需一次就行了,后续只要Unity或.NET版本相同,都可以重复进行使用

在线 protobuff转java类_网络_06

2.2 方案二 从Github下载并自己生成.dll

2.2.1 下载Probuff

Protoc-xx版本-你的系统版本.zip

上面的Github链接Github链接Github链接,选择你要使用的版本,点进去,往下拉找到Protobuf-xx版本.zip,下载下来

在线 protobuff转java类_网络_07

解压出来是这样,选择你的语言版本打开,我们Unity是用的.NET,也就是csharp版本

在线 protobuff转java类_反序列化_08

进去后找到src文件夹,点开

在线 protobuff转java类_反序列化_09

2.2.2 VS打开解决方案

使用VS打开这个Google.Protobuf.sln文件

在线 protobuff转java类_网络_10

在线 protobuff转java类_网络_11

如果项目成功打开,请跳转到2.2.4步骤继续下一步

2.2.3 安装.NET SDK

如果弹出这个窗口就代表你的电脑没有安装匹配的.NET SDK版本,请继续往下看

在线 protobuff转java类_在线 protobuff转java类_12

需要根据你的Unity版本下载安装匹配的.NET版本,那怎么看你的Unity适用的版本呢,可以在Unity顶部工具栏→Help→Unity Manual中查询

在线 protobuff转java类_反序列化_13

如果你安装unity的时候没有勾选安装Unity Document,也可以在官网找到

Unity Document地址

记得左上角切换成你的Unity版本

在线 protobuff转java类_在线 protobuff转java类_14


 

然后在搜索框搜索.net api,在搜索结果中找到.NET Profile support,点击进入

在线 protobuff转java类_反序列化_15

下拉就可以看到你的Unity版本所匹配的.NET版本了,上面的是Unity所使用的.NET版本,左边竖排的是.NET的不同平台版本,可以看到适配度最好的是.NET Standard版本

在线 protobuff转java类_在线 protobuff转java类_16

知道版本后,就可以去微软下载.NET了

适用于VS的.NET下载

进去后往下拉找到.NET Standard,他让我们直接下载.NET/.NET Core,我们可以点进右边看看具体对应的版本

在线 protobuff转java类_网络_17

在线 protobuff转java类_网络_18

选择一个合适的.NET/.NET版本,回到刚才的界面下载,笔者这边选择的是.Net 7.0版本,下载后直接安装就行了,这里需要注意的是,如果你的VS版本太低,是无法使用.NET 7.0的,可以使用VS Installer安装一下VS 2022版本

在线 protobuff转java类_在线 protobuff转java类_19

回到刚才的Protobuf文件夹下的src目录下,新建一个global.json脚本

在线 protobuff转java类_网络_20

里面填上你的.NET SDK版本号,这时候打开Google.Protobuf.sln就不会报错了

{
  "sdk": {
    "version": "7.0.407",
  }
}

2.2.4 生成.dll文件

点击VS顶部工具栏的调试开始运行(不调试),等待执行完毕

在线 protobuff转java类_在线 protobuff转java类_21

src/Google.Protobuf就会生成一个bin目录,如果你刚才点的是调试,就会生成Debug目录,我们使用的是Release模式,生成了Release目录,里面就是这样

在线 protobuff转java类_在线 protobuff转java类_22

注意,这时候我们不要直接使用.netstandard2.0的版本,因为.netstandard2.0文件目录下没有生成System.Buffers.dll等文件,导入Unity无法正常识别

我们选择使用.net45的版本,点进去,将所有文件拷贝到你的Unity Assets目录下的Plugins文件夹下,建议建个Protobuf文件夹,放在里面,这时候就可以使用了

在线 protobuff转java类_在线 protobuff转java类_23

在线 protobuff转java类_反序列化_24

3.使用Protoc工具生成.cs文件

3.1 下载Protoc

在刚才的Github链接,下载protoc-xx版本-你的系统版本.zip,注意,protoc版本和之前下的protobuf版本得是完全一致的

在线 protobuff转java类_反序列化_25

解压完是这样

在线 protobuff转java类_反序列化_26

3.2 进入Bin文件夹目录

回到前面下的Protoc文件目录下,进入bin文件夹,可以看到里面只有一个protoc.exe文件

在线 protobuff转java类_网络_27

3.3 写一个.proto例子

在本目录下,新建一个.proto后缀的文件,这个就是我们定义的protobuf类型的数据结构,这里写一个Animal动物的例子

在线 protobuff转java类_反序列化_28

点开编辑你的数据结构

第一行指定使用的Proto版本的语法,不指定则默认使用Proto2处理,第二行定义了在C#中调用Animal的命名空间

这里例子中定义了三个字段,分别是字符串类型的动物类型,int整型的动物id号,float浮点型的动物重量,protobuff支持的其他数据类型可自行搜索

syntax="proto3";
package MyProtobufData;		//自定义命名,在C#用使用这个数据结构需要using

message Animal
{
	string Type = 1;
	int32 ID = 2;
	float Weight =3;
}

3.4 使用proto.exe将.proto转换成可以在C#中使用的.cs文件

建一个.bat批处理命令,这样就不用每次都非常麻烦地使用命令进行转换了

在线 protobuff转java类_在线 protobuff转java类_29

打开后编辑转换的命令,--proto_path就是.proto文件所在的路径.(!!!注意,这里是个小点)代表protoc.exe所在的当前目录空一格 ,后面再输入你的.proto文件路径和完整名字--csharp_out是你指定的.cs文件生成的位置,笔者这边就不指定了,直接原目录生成

protoc.exe  --proto_path =. Animal.proto --csharp_out=.

编辑完毕双击执行.bat文件,就会生成一个同名的.cs文件

在线 protobuff转java类_序列化_30

4.在Unity中使用Protobuff

4.1 将生成的.cs文件导入我们的Unity项目中

在线 protobuff转java类_序列化_31

4.2 建一个Proto工具类,用来进行对我们的数据进行序列化和反序列化

using Google.Protobuf;
using UnityEngine;
using System;

public class ProtobufMgr
{
    public static byte[] Serialize(IMessage message)
    {
        return message.ToByteArray();
    }

    public static T DeSerialize<T>(byte[] packet) where T : IMessage, new()
    {
        IMessage message = new T();
        try
        {
            return (T)message.Descriptor.Parser.ParseFrom(packet);
        }
        catch (Exception e)
        {
            throw e;
        }
    }
}

4.3 写一个测试类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MyProtobufData;//记得using刚才.proto内定义的命名空间
using System;
using System.IO;
using System.Text;

public class ProtobufTest : MonoBehaviour
{

    private void Start()
    {
        //定义一个四百斤的大胖橘
        Animal animal = new Animal()
        {
            Type = "东北金渐层",
            ID = 1,
            Weight = 400,
        };
        //序列化
        byte[] bytes = ProtobufMgr.Serialize(animal);
        Debug.Log("长度"+bytes.Length);
        Debug.Log(Encoding.UTF8.GetString(bytes));
        Debug.Log("————————————————————————");

        //反序列化
        Animal newAnimal = ProtobufMgr.DeSerialize<Animal>(bytes);
        Debug.Log(newAnimal.Type);
        Debug.Log(newAnimal.ID);
        Debug.Log(newAnimal.Weight);
    }
}

可以看到成功进行了序列化和反序列化

在线 protobuff转java类_unity_32

简单小结

看完上面的步骤,你已经学会在Unity中使用Protobuf进行序列化了,我们进行网络传输通信时使用的就是byte[]字节数组序列,发送方发送数据结构序列化后的byte[],接收方收到byte[]反序列化成原来的数据结构,就成功进行了网络的通信