? ? ? ?#region 知識點一 什么是 Protobuf
? ? ? ? //Protobuf 全稱是 protocol - buffers(協議緩沖區)
? ? ? ? // 是谷歌提供給開發者的一個開源的協議生成工具
? ? ? ? // 它的主要工作原理和我們之前做的自定義協議工具類似
? ? ? ? // 只不過它更加的完善,可以基于協議配置文件生成
? ? ? ? //C++、Java、C#、Objective - C、PHP、Python、Ruby、Go
? ? ? ? // 等等語言的代碼文件
? ? ? ? // 它是商業游戲開發中常常會選擇的協議生成工具
? ? ? ? // 有很多游戲公司選擇它作為協議工具來進行網絡游戲開發
? ? ? ? // 因為它通用性強,穩定性高,可以節約出開發自定義協議工具的時間
? ? ? ? //protocol - buffers 官網
? ? ? ? //https://developers.google.com/protocol-buffers
? ? ? ? #endregion
? ? ? ? #region 知識點二 Protobuf 的使用流程
? ? ? ? //1. 下載對應語言要使用 Protobuf 相關內容
? ? ? ? //2. 根據配置規則編輯協議配置文件
? ? ? ? //3. 用 Protobuf 編譯器,利用協議配置文件生成對應語言的代碼文件
? ? ? ? //4. 將代碼文件導入工程中進行使用
? ? ? ? #endregion
? ? ? ? #region 知識點三 下載 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 插件文件夾中
? ? ? ? #endregion
? ? ? ? #region 知識點四 下載Protobuf相關內容—準備編譯器
? ? ? ? //1.在官網中前往下載地址
? ? ? ? // ?protocol - buffers官網
? ? ? ? // ?https://developers.google.com/protocol-buffers
? ? ? ? //2.下載protoc - 版本 - win32或者64(根據操作系統而定)
? ? ? ? //3.解壓后獲取bin文件夾中的protoc.exe可執行文件,
? ? ? ? // ?可將其放入Unity工程中,方便之后的使用(你也可以不放入Unity工程,記住它的路徑即可)
? ? ? ? #endregion
? ? ? ? #region 總結
? ? ? ? //Protobuf全稱protocol-buffers
? ? ? ? //是谷歌提供給開發者的開源協議生成工具
? ? ? ? //我們要使用它主要準備兩步
? ? ? ? //1. 下載對應Csharp版本,生成DLL包文件導入工程中(之后的基類,序列化反序列化都基于DLL包中寫好的內容)
? ? ? ? //2. 下載對應操作系統的protoc編譯器,用于之后生成代碼文件(之后根據配置文件生成代碼都是通過該應用程序)
? ? ? ? #endregion
#region 知識點一 回顧自定義協議生成工具中的配置文件//我們在自定義協議配置工具相關知識點中//使用的是xml文件進行配置//我們只需要基于xml的規則//按照一定規則配置協議信息//之后獲取xml數據用于生成代碼文件//在Protobuf中原理是一樣的//只不過Protobuf中有自己的配置規則//也自定義了對應的配置文件后綴格式#endregion#region 知識點二 配置后綴//Protobuf中配置文件的后綴統一使用//.proto//可以通過多個后綴為.proto的配置文件進行配置#endregion#region 知識點三 配置規則#region 規則1 注釋方式//方式1/*方式2*/#endregion#region 規則2 第一行版本號//syntax = "proto3";//如果不寫 默認使用proto2#endregion#region 規則3 命名空間//package 命名空間名;#endregion#region 規則6 特殊標識//1:required 必須賦值的字段//2:optional 可以不賦值的字段//3:repeated 數組//4.map 字典#endregion#region 規則7 枚舉//enum 枚舉名{// 常量1 = 0;//第一個常量必須映射到0// 常量2 = 1;//}#endregion#region 規則8 默認值//string-空字符串//bytes-空字節//bool-false//數值-0//枚舉-0//message-取決于語言 C#為空#endregion#region 規則9 允許嵌套#endregion#region 規則10 保留字段//如果修改了協議規則,刪除了部分內容//為了避免更新時,重新使用已經刪除了的編號//我們可以利用 reserved 關鍵字來保留字段//這些內容就不能再被使用了//message Foo {// reserved 2, 15, 9 to 11;// reserved "foo", "bar";//}#endregion#region 規則11 導入定義//import "配置文件路徑";//如果你在某一個配置中,使用了另一個配置的類型//則需要導入另一個配置文件名#endregion#endregion#region 總結//我們需要掌握Protobuf的配置規則//之后才能使用工具將其轉化為C#腳本文件#endregion
test.proto和test2.proto文件
//規則二:版本號
syntax="proto3";//決定了proto文檔的版本號//規則一:注釋方式
//注釋方式一
/*注釋方式二*/ //規則十一: 導入定義
import "test2.proto";
//規則三:命名空間
package GamePlayerTest;//這決定了命名空間//規則四:消息類
message TestMsg{//規則五:成員類型和唯一編號//浮點數// =1不代表默認值,而是代表唯一號 方便我們進行序列化//required - 必須賦值的字段 proto2//optional - 可以不賦值的字段//requiredfloat testF = 1;//C#-float optional double testD = 2;//C#-double //變長編碼//所謂變長 就是會根據 數字的大小 來使用對應的字節數來存儲//Protobuf幫助我們優化的部分 可以盡量少的使用字節數 來存儲內容int32 testInt32 = 3;//C#-int 它不太適用于表示負數 請使用sint32//1 2 4 8int64 testInt64 = 4;//C#-long 它不太適用于表示負數 請使用sint64//更實用表示負數類型的的整形sint32 testSInt32 = 5;//C#-int 適用于表示負數的整形sint64 testSint64 = 6;//C#-long 適用于表示負數的整形//無符號 變長編碼//1 2 4 uint32 testUInt32 = 7;//C#-uint 變長的編碼uint64 testUInt64 = 8;//C#-ulong 變長的編碼//固定字節數的類型fixed32 testFixed32 = 9;//C#-uint 它通常表示大于2的28次方的數,比uint32更有效 始終是4個字節fixed64 testFixed64 = 10;//C#-ulong 它通常表示大于2的56次方的數,比uint64更有效 始終是8個字節sfixed32 testSFixed32 = 11;//C# - int 始終是4個字節 sfixed64 testSFixed64 = 12;//C# - long 始終是8個字節//其它類型bool testBool = 13;//C#-boolstring testStr = 14;//C#-stringbytes testBytes = 15;//C# - BytesString 字節字符串//數組Listrepeated int32 listInt = 16;//C# - 類似List<int>的使用//字典Dictionary map<int, string> testMap = 17; //C# - 類似Dictionary<int,string>的使用//枚舉成員變量的聲明 需要唯一編碼TestEnum testEnum = 18;//聲明自定義類對象 需要唯一編碼//默認值是nullTestMsg2 testMsg2 = 19;//嵌套一個類在另一個類中 相當于是內部類message TestMsg3{int32 testInt32 =1;}TestMsg3 testMsg3 = 20;enum TestEnum2{NORMAL = 0;//第一個常量必須映射到0BOSS = 1;}TestEnum2 testEnum2 = 21;//int32 testInt323333 = 22;bool testBool34555 = 23;GameSystemTest.HeartMsg testHeart = 24;//告訴編譯器 22 被占用 不準用戶使用//之所以有這個功能 是為了在版本不匹配時 反序列化時 不會出現結構不統一//解析錯誤的問題reserved 22;reserved "testInt323333";}
//枚舉的申明
enum TestEnum{NORMAL = 0;//第一個常量必須映射到0BOSS = 5;
}
message TestMsg2{int32 testInt32 =1;
}
syntax="proto3";//決定了proto文檔的版本號
package GameSystemTest;//這決定了命名空間
message HeartMsg
{int64 time = 1;
}