当前位置: 首页 > news >正文

Unity网络开发--第三方协议工具Protobuf

什么是 Protobuf

Protobuf 全称是 protocol-buffers(协议缓冲区)

是谷歌提供给开发者的一个开源的协议生成工具

它的主要工作原理和我们之前做的自定义协议工具类似

只不过它更加的完善,可以基于协议配置文件生成

C++、Java、C#、Objective-C、PHP、Python、Ruby、Go 等等语言的代码文件

它是商业游戏开发中常常会选择的协议生成工具

有很多游戏公司选择它作为协议工具来进行网络游戏开发

因为它通用性强,稳定性高,可以节约出开发自定义协议工具的时间

protocol-buffers 官网//https://developers.google.com/protocol-buffers

下载 Protobuf 相关内容 — 准备 DLL 文件

  1. 在官网中前往下载地址//protocol-buffers 官网 https://developers.google.com/protocol-buffers

  2. 下载 protobuf-csharp

  3. 解压后打开 csharp\src 中的 Google.Protobuf.sln

  4. 选择 Google.Protobuf 右键生成 dll 文件

  5. 在 csharp\src\Google.Protobuf\bin\Debug 路径下找到对应.net 版本的 Dll 文件(我们使用 4.5 即可)

  6. 将 net45 中的 dll 文件导入到 Unity 工程中的 Plugins 插件文件夹中

下载 Protobuf 相关内容 — 准备编译器

  1. 在官网中前往下载地址 protocol-buffers 官网 https://developers.google.com/protocol-buffers

  2. 下载 protoc - 版本 - win32 或者 64(根据操作系统而定)

  3. 解压后获取 bin 文件夹中的 protoc.exe 可执行文件,可将其放入 Unity 工程中,方便之后的使用(你也可以不放入 Unity 工程,记住它的路径即可)

创建proto结尾的配置文件

配置文件定义规则

//规则1:版本号
syntax = "proto3"; //版本号,不写默认使用proto2//规则2:注释方式
//注释方式1
/*注释方式2*///规则11:导入定义
import "test2.proto";//规则3:命名空间
package GamePlayerTest;//定义命名空间//规则4:消息类
message PlayerMsg{/*规则5:成员类型和唯一编号浮点数: float, double整数:变长编码- int32,int64,uint32,uint64固定字节数- fixed32,fixed64,sfixed32,sfixed64其他类型:bool,string,bytes唯一编号 配置成员时 需要默认给他们一个编号 从1开始这些编号用于标识中的字段消息二进制格式*/float testF = 1; //1不是float的默认值,而是唯一编号,方便序列化和反序列化的处理double testD = 2;int32 testInt32 = 3; //所谓边长就是根据数字的大小来使用对应的字节数来存储int64 testInt64 = 4;//sint跟适用于表示负数sint32 testSint32 = 5;sint64 testSint64 = 6;//uint无符号uint32 testUint32 = 7;uint64 testUint64 = 8;fixed32 testFixed32 = 9; //uint 通常用于表示大于2的28次方的数fixed64 testFixed64 = 10; //ulong 通常用于表示大于2的56次方的数sfixed32 testSfixed32 = 11; //intsfixed64 testSfixed64 = 12; //longbool testBool = 13;string testString = 14;bytes testBytes = 15; //BytesString 字节字符串/*规则6:特殊标识1:required  必须赋值的字段2:optional  可以不赋值的字段3:repeated  数组4:map       字典*/repeated int32 listInt32 = 16; //类似List<int>的使用map<int32,string> testMap = 17; //类型Dictionary<int,string>的使用//枚举成员变量的声明TestEnum testEnum = 18;//声明自定义类对象TestMsg2 testMsg2 = 19;//嵌套类 相当于内部类message TestMsg3{int32 testInt32 = 1;}//int32 tesInt22222222 = 20;//告诉编译器22被占用 不准用户使用//之所以有这个功能 是为了在版本不匹配时 反序列化时不会出现结构不统一解析错误的问题reserved 20;reserved "tesInt22222222";GameSystemTest.HeartMsg testHeart = 21;
}/*
规则7:枚举
enum 枚举名{常量1 = 0; //第一个常量必须映射到0常量2 = 1;}
*/
enum TestEnum{NORMAL = 0;BOSS = 5;PLAYER = 6;
}message TestMsg2{int32 testInt32 = 1;
}

利用 protoc.exe 编译器生成脚本文件

  1. 打开 cmd 窗口

  2. 进入 protoc.exe 所在文件夹(也可以直接将 exe 文件拖入 cmd 窗口中)

  3. 输入转换指令//protoc.exe -I = 配置路径 --csharp_out = 输出路径 配置文件名

注意:路径不要有中文和特殊符号,避免生成失败

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class lesson12 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){GamePlayerTest.PlayerMsg player = new GamePlayerTest.PlayerMsg();player.TestF = 10.0f;player.TestEnum = GamePlayerTest.TestEnum.Player;player.ListInt32.Add(1);print(player.ListInt32[1]);player.TestMap.Add(1,"xxxxx");print(player.TestMap[1]);player.TestHeart = new GameSystemTest.HeartMsg();player.TestHeart.Time = 10;}// Update is called once per framevoid Update(){}
}

自动生成工具

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEngine;public class ProtobufTool
{private static string PRPTP_PATH = "C:\\protobuf\\proto";private static string PROTO_PATH = "C:\\protobuf\\protoc.exe";private static string CSHARP_PATH = "C:\\protobuf\\csharp";[MenuItem("ProtocolBuf/生成C#代码")]private static void GenerateCSharp(){DirectoryInfo info = Directory.CreateDirectory(PRPTP_PATH);FileInfo[] fileInfos = info.GetFiles();for (int i = 0; i < fileInfos.Length; i++){if (fileInfos[i].Extension == ".proto"){ Process cmd = new Process();cmd.StartInfo.FileName = PROTO_PATH;cmd.StartInfo.Arguments = $"-I={PRPTP_PATH} --csharp_out={CSHARP_PATH} {fileInfos[i]}";cmd.Start();UnityEngine.Debug.Log(fileInfos[i] + "生成结束");}}}
}

序列化和反序列化

using Google.Protobuf;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;public class lesson12 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){GamePlayerTest.PlayerMsg player = new GamePlayerTest.PlayerMsg();player.TestF = 10.0f;player.TestEnum = GamePlayerTest.TestEnum.Player;player.ListInt32.Add(1);print(player.ListInt32[1]);player.TestMap.Add(1,"xxxxx");print(player.TestMap[1]);player.TestHeart = new GameSystemTest.HeartMsg();player.TestHeart.Time = 10;//序列化using (FileStream fs = File.Create(Application.persistentDataPath + "/PlayerMsg.han")){player.WriteTo(fs);}//反序列化using (FileStream fs2  = File.OpenRead(Application.persistentDataPath + "/PlayerMsg.han")){GamePlayerTest.PlayerMsg playerMsg = GamePlayerTest.PlayerMsg.Parser.ParseFrom(fs2);}byte[] bytes = null;//得到序列化字节数组using (MemoryStream ms =new MemoryStream()){player.WriteTo(ms);bytes = ms.ToArray();}//从字节数组反序列化using (MemoryStream ms = new MemoryStream(bytes)){GamePlayerTest.PlayerMsg playerMsg = GamePlayerTest.PlayerMsg.Parser.ParseFrom(ms);}}// Update is called once per framevoid Update(){}
}
http://www.dtcms.com/a/479256.html

相关文章:

  • 城阳网站建设公司wordpress首页文章缩略图插件
  • 兼职招聘网站中国最新军事新闻
  • MATLAB做一个简单的元胞自动机:森林火灾模拟
  • 嵌入式开发培训机构排名seo自动推广工具
  • 百度网盘公益解析网站下载限速一边去
  • 站酷网首页蛋糕店微网站
  • 2025年--Lc183--198. 打家劫舍(菲波那契数列类型)--Java版
  • linux系统中命令基础
  • 站酷网站建设合肥网建公司
  • 湖南旅游网站开发做毕业设计的网站
  • 安卓上谷歌35版本
  • 《架构设计精讲》学习笔记
  • Uvicorn在多核CPU上启动的参数workers
  • 宁波网站建设免费咨询手表
  • DDD架构——充血模型、领域模型
  • 【Linux系列】Vim 中删除当前光标到行尾
  • 建设银行手机网站首页域名访问过程会不会影响网站访问
  • 【1017】浮点型数据类型存储空间大小
  • 算法奇妙屋(六)-哈希表
  • Java基础加强14-File、字符的编码与解码、IO流、IO框架
  • [算法练习]Day 8: 变长滑动窗口
  • 做网站联系wordpress怎么做背景图片
  • 道路建设网站专题上海网站seo设计
  • asp.net做网站系统wordpress 首页不显示
  • GESP2025年9月认证C++四级( 第三部分编程题(1)排兵布阵)
  • 论文解读 -- A FOUNDATION MODEL FOR MUSIC INFORMATICS
  • Redis-管道和发布订阅
  • 做网站最大可以做多少g代做网站多少钱
  • PostgreSQL 模式(Schema)详解
  • 网站网页制作及优化网站建设收费明细表