[TOC]
1. Unity protobuff3.0庫的選擇
網上搜查發(fā)現(xiàn),目前可供unity使用的protobuff3.0的庫主要有2個蹦狂,一個是
protobuf-net誓篱,另一個是
protobuf3-for-unity,選擇哪一個呢凯楔?
- 從github上的Star數(shù)量來看:protobuf-net的1400+遠勝于protobuf3-for-unity的136
- 從更新日期來看窜骄,protobuf-net最近幾天都有post,而protobuf3-for-unity最近的動作則是在十個月之前了啼辣。
但是為什么最終選擇了protobuf3-for-unity?因為我使用Nuget :
Install-Package protobuf-net
安裝protobuf-net一直不成功御滩,報錯說指令集不兼容鸥拧,我們知道党远,unity支持的.net版本是2.0和3.5,protobuf-net最新支持的是.NET Framework 4.0+的富弦,沒法用沟娱,官網上說v2.1.0的版本支持.NET Framework 2.0/3.0/3.5,于是安裝命令改成:
Install-Package protobuf-net -version 2.1.0
還是報一樣的錯誤:
Install-Package protobuf-net
正在嘗試收集與目標為“.NETFramework,Version=v3.5,Profile=Unity Subset v3.5”的項目“TestMj”有關的>包“protobuf-net.2.2.1”的依賴項信息
收集依賴項信息花費時間 1.11 ms
正在嘗試解析程序包“protobuf-net.2.2.1”的依賴項腕柜,DependencyBehavior 為“Lowest”
解析依賴項信息花費時間 0 ms
正在解析操作以安裝程序包“protobuf-net.2.2.1”
已解析操作以安裝程序包“protobuf-net.2.2.1”
從“nuget.org”檢索包“protobuf-net 2.2.1”
GET https://api.nuget.org/packages/protobuf-net.2.2.1.nupkg
OK https://api.nuget.org/packages/protobuf-net.2.2.1.nupkg 69 毫秒
正在安裝 protobuf-net 2.2.1济似。
安裝失敗。正在回滾...
程序包“protobuf-net.2.2.1”不存在于項目“TestMj”中
程序包“protobuf-net.2.2.1”不存在于文件夾“C:\Users\IGG\AppData\Local\Temp\TestMj\packages”中
執(zhí)行 nuget 操作花費時間 701.07 ms
Install-Package : 無法安裝程序包“protobuf-net 2.2.1”盏缤。你正在嘗試將此程序包安裝到目標為“.NETFramework,Version=v3.5,Profile=Unity Subset v3.5”的項目中砰蠢,但該程序包不包含任何與該框架兼容的程序集引用或內容文件。有關詳細信息唉铜,請聯(lián)系程序包作者台舱。
所在位置 行:1 字符: 16
- Install-Package <<<< protobuf-net
- CategoryInfo : NotSpecified: (:) [Install-Package], Exception
- FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
已用時間: 00:00:01.6763018
參考這個最新版的release note里面,好像是有針對這個問題做修復潭流,但是我試了Install-Package protobuf-net -version 2.3.0-alpha
沒效果竞惋,不知道是不是用法不對,不想繼續(xù)浪費時間灰嫉,就果斷選擇protobuf3-for-unity拆宛。等下次閑了再去試試。
v2.3.0-alpha
- net20 / net35 targets reinstated for NuGet build (#262)
2. Unity protobuff3.0整合及測試
整合:
- 新建一個unity3d項目
- 下載protobuf3-for-unity讼撒,解壓浑厚。
- 根據項目首頁readme.md的指示,安裝對應版本的.NET Core
- 雙擊解壓后的得到的build_packages.bat椿肩,進行編譯瞻颂,如果編譯失敗,一定是.Net Core版本選擇錯了郑象,卸載掉原來的重新下載一個安裝再試贡这。
- 編譯成功的話,protobuf3-for-unity-3.0.0\src\Google.Protobuf\bin\Release\net35目錄下會有一個Google.Protobuf.dll厂榛,這個dll就是我們要用在unity項目里面的盖矫。如果自己編譯不出來,也可以在這里直接下載击奶,解壓里面就有一個作者編好的dll辈双。
- 把上面的dll拷貝到unity項目的Assets\Plugins\目錄下。如果沒有Plugins目錄柜砾,自己創(chuàng)建一個湃望。
注:protobuf3-for-unity-3.0.0\src\Google.Protobuf工程源碼可以看看,有助于了解protobuff3.0的實現(xiàn)。
測試:
- 在測試之前证芭,還需要下載一個protoc瞳浦,也就是代碼生成器,用來把我們定義的proto文件生成C#對應的類废士,我們是protobuff3.0版本叫潦,要選對版本、選對系統(tǒng)官硝,我是win7系統(tǒng)矗蕊,所以是下載這個protoc-3.0.0-win32.zip,注意需要的是protoc氢架,不需要把源代碼下載下來傻咖。源代碼在上面下載的protobuf3-for-unity里面已經有了。解壓后在protoc-3.0.0-win32\bin目錄下能看到一個protoc.exe
- 把下面代碼保存成addressbook.proto文件放在protoc.exe同級目錄下
syntax = "proto3";
package tutorial;
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
}```
- 打開一個cmd窗口达箍,cd到protoc.exe所在目錄没龙,輸入``` protoc --csharp_out=./ addressbook.proto ```然后回車,可以看到缎玫,同級目錄下生成了一個Addressbook.cs文件硬纤,這個文件需要加在unity3d工程的Assets\Scripts目錄下,不放在Scripts目錄下應該也沒影響赃磨。
- 新建一個C#腳本筝家,掛在場景任意一個物體上,只要啟動的時候能觸發(fā)這個腳本的調用就可以了邻辉。
- 在新建的腳本的Start函數(shù)里寫上測試代碼:
``` C#
// 我的全部using是這些溪王,因為已經添加了網絡部分的,雖然到這一步還沒用到
using Google.Protobuf;
using Google.Protobuf.Examples.AddressBook;
using Google.Protobuf.WellKnownTypes;
using System;
using System.IO;
using System.Net.Sockets;
using UnityEngine;
void Start () {
// 這些代碼是在protobuf3-for-unity-3.0.0\src\AddressBook\Program.cs里面拷貝的
byte[] bytes;
// Create a new person
Person person = new Person
{
Id = 1,
Name = "Foo",
Email = "foo@bar",
Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
};
using (MemoryStream stream = new MemoryStream())
{
// Save the person to a stream
person.WriteTo(stream);
bytes = stream.ToArray();
}
Person copy = Person.Parser.ParseFrom(bytes);
AddressBook book = new AddressBook
{
People = { copy }
};
bytes = book.ToByteArray();
// And read the address book back again
AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
// The message performs a deep-comparison on equality:
if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
{
throw new Exception("There is a bad person in here!");
}
}
- 添加完以上代碼值骇,在ide里打個斷點莹菱,unity里面點啟動,一步步斷點跟下來可以查看究竟吱瘩。
3. 建立與服務端通信連接道伟,使用protobuff編碼解碼
4. 處理與Netty服務器通信的粘包、拆包
先去吃飯使碾,3和4部分放在下一篇