Unity 的ProtoBuff 相关批处理

孙广东  2015.9.25

批处理的好处就不说了。

ProtoBuff这里也不多说什么, 看最后面的介绍吧!

先看看批处理脚本

@echo off

:: 注: 这是放在Unity的Assets 下的文件
:: cd..是进入上一层目录 cd\是进入根目录

set unityDllPath=%cd%\Assets\Pluginscd PXProtocolProject
echo 进入路径: %cd%
set protoSourcePath=%cd%\ProtoFileset protoImportsPath=%cd%

:: 进入这个目录
cd CSharpTool
echo 进入路径: %cd%
set protoBinPath=%cd%\ProtobinFileset csharpSourceOutputPath=%cd%\CSharpCodeset csharpProjectPath=%cd%\ProtoDllGen\ProtoProject\ProtoFileToCSharpFile:: for %%i in (*.*) do echo %%i                                              

echo generateing csharp codes...
:: 生成C#代码,    for循环对每个文件进行操作
for %%i in (%protoSourcePath%*.*) do (
	%cd%\protoc.exe --descriptor_set_out=%protoBinPath%%%~ni.protobin --include_imports %%i --proto_path=%protoImportsPath%
	%cd%\protogen.exe %protoBinPath%%%~ni.protobin -output_directory=%csharpSourceOutputPath%
	 )

:: 将生成的C#文件 拷贝到 Dll工程内
echo copying csharp code file to project..
copy %csharpSourceOutputPath%*.cs %csharpProjectPath%

echo compile the c# dLL project..

set msBuildDir=%WINDIR%\Microsoft.NET\Framework\v2.0.50727
call %msBuildDir%\msbuild.exe  %cd%\ProtoDllGen\ProtoProject\ProtoDllGen.csproj /t:Rebuild /p:Configuration=Release /p:VisualStudioVersion=14.0

:: 将编译的生成文件拷贝到 Unity项目中, 让Unity执行编译
echo copying the dLL to unity project..
copy %cd%\ProtoDllGen\ProtoProject\bin\Release\*.dll %unityDllPath%

pause

:: 孙广东 添加 :要求,这个直接放到unity项目中根目录下。 而这个ptoto项目要相对于Unity项目是平行的。即如下:XXXXX\px\.git  和  XXXXX\px\PXProDoc\.git        // unity项目要 忽略PXProDoc 这个文件夹
:: 然后拷贝 就方便了

看看运行结果:

在 Unity 中双击如下文件:

结果在 Untiy的 文件夹 下:

。。。。

废话不多说。  继续阅读

首先, Proto协议文件是 服务器和客户端所共享的。  服务器根据它生成对应的语言。   客户端根据它生成对应的语言(Unity中就是C#了)

所以可以想象的是:团队的项目中包括了:服务器project、客户端project、ptotoBuff协议project(这些协议由服务器定义就行了, 然后)

ProtoBuf对于很多人而言并不陌生,应该也在很多项目中得以应用了。 那么现在我们就来看看,在Unity中使用的具体步骤。

步骤1 :

Google 官方的Protobuf是不支持C#语言的,好在有很多开发者为ProtoBuf开发了支持C# (.net)的插件, 打开网址 http://code.google.com/p/protobuf-net/, 这是。net版本的主页。

步骤2:

下载 protobuf-net_r668.zip, 将其解压, 然后将路径Full\unity内的所有文件复制到Unity工程目录内,这里建议复制到 Plugins目录内。

步骤3:

使用任意文件编辑器创建第一个协议文件,本地将文件命名为 chatapp.proto,然后定义协议如下:

package ChatAPP;

message User {

required string name = 1;

required string chat = 2;

optional string email = 3;

}

message Chat {

repeated User user = 1;

}

这里我们可以将package看作名称域 , message看作是class, User有3个成员,用户名、聊天内容和 E-mail。

标识符required表示这是个必须的数据, optional表示这是可选的。

在 Chat中,只有一个成员是User,它的前面有一个标识符repeated,表示Chat可以拥有多个 User。

步骤4 :

在 protobuf-net_r668压缩包内有一个 ProtoGen的文件夹, 将chatapp.proto复制到这个文件夹下。

步骤5:

在Windows开始菜单输入 CMD,打开控制台窗口,将路径设置到 ProtoGen,然后输入下面的脚本,转出文件chatapp.cs ,将这个文件复制到客户端和服务器端。

protogen -i:chatapp.proto-o:chatapp.cs

注意,因为每次修改 .proto文件都要重新生成新的.cs 文件,为了方便, 可以将生成 .cs文件的脚本写在一个.cmd文件夹中,这样每次操作只需要选择这个文件即可,如图所示:

步骤6:

在C# 中序列化User的方法如下:

ChatAPP.User user = new ChatAPP.User();

user.name = "用户甲";

user.chat = "hello,world";

using (System.IO.MemoryStream stream =new System.IO.MemoryStream())

{

ProtoBuf.Serializer.Serialize<ChatApp.User>(stream, user);

Byte[] bs = Stream.ToArray();

}

步骤7:

从一个byte 数组中解析User的方法如下:

// bs 是一个byte数组, 他应当是从网络或者文件中得到的

using (System.IO.MemoryStreamstream = new System.IO.MemoryStream(bs))

{

ProtoBuf.Meta.RuntimeTypeModelmodel = ChatSerializer.Create();

user2 =(ChatAPP.User)model.Deserialize(stream, null, typeof(ChatAPP.User));

}

步骤8:

repeated类型的数据比较特殊,它在C#中实际是一个数组:

ChatAPP.Chat chat;

chat.user.Add(user);

虽然使用 Protobuf很简单,但当将它使用到 IOS平台会遇到麻烦, .Net版本的ProtoBuf 用到了C#的反射功能,这个功能当前在苹果 ios系统中是不能使用的, 好在.Net 版本的ProtoBuf提供了一个办法解决这个问题。这里以前面创建的chatapp.ptoto这个文件为例,操作步骤如下:

步骤1:

在Visual Studio 中创建要给C# de Class Library 工程,将前面得到的 chatapp.cs 文件添加到这个工程。

步骤2:

在工程中选择 Add Reference 将 Protobuf 提供的 protobuf-net.dll 添加到当前工程,如图所示:

步骤3:

编译当前工程,在输出目录生成一个叫 ProtoLib.dll 的文件, 这个文件的名称并不重要,如图所示:

步骤4:

添加一个新的C# 控制台工程,将protobuf-net.dll 和上一步生成的 ProtoLib.dll 添加到这个工程中, 添加代码如下:

using System;

usingSystem.Collections.Generic;

namespace ProtoBuilder

{

class Program

{

static void Main(string[] args)

{

ProtoBuf.Meta.RuntimeTypeModelmodel =

ProtoBuf.Meta.RuntimeTypeModel.Create();

model.Add(typeof(ChatAPP.Chat),true);

model.Add(typeof(ChatAPP.User),true);

model.Compile("ChatSerializer","ChatSerializer.dll");

}

}

}

这里的代码首先创建了一个 RuntimeTypeModel 对象, 然后将.proto文件中定义的类都添加到该对象中,最后的参数 ChatSerializer是类的名称域, ChatSerializer.dll 是生成的文件名。

步骤5:

编译当前工程,在输出目录找到ProtoBuilder.exe 文件, 双击运行它,生成ChatSerializer.dll 文件, 如图7-8所示, 将 ChatSerializer.dll 和 ProtoLib.dll 这两个文件都复制到Unity工程中。注意, 在Unity工程中已经不需要 chatapp.cs这个文件, dll文件中已经包括了它。

从最初生成的Protobuf的.cs文件,到反复编译的dll 文件, 在将他们复制到Unity工程中是件非常麻烦的事, 在实际的项目中,最好编写一些批处理脚本来完成这些事情。

步骤6:

在Unity的C# 脚本中序列化 User ,注意与之前代码的不同。

ChatAPP.User user = new ChatAPP.User();

user.name = "用户甲";

user.chat = "hello,world";

byte[] bs;

using (System.IO.MemoryStream stream =new System.IO.MemoryStream())

{

ProtoBuf.Meta.RuntimeTypeModelmodel = ChatSerializer.Create();

model.Serialize(stream, user);

bs = stream.ToArray();

}

步骤7:

反序列化的代码如下:

ChatAPP.User user2;

using (System.IO.MemoryStream stream =new System.IO.MemoryStream(bs))

{

ProtoBuf.Meta.RuntimeTypeModelmodel = ChatSerializer.Create();

user2 =(ChatAPP.User)model.Deserialize(stream, null, typeof(ChatAPP.User));

}

每次序列化、反序列化写这么多代码很麻烦,我们可以将他们写为泛型的函数,代码如下:

// 序列化

public static byte[]ProtoRuntimeSerialize<T>(T t)

{

byte[] bs;

using (System.IO.MemoryStream stream =new System.IO.MemoryStream())

{

ProtoBuf.Meta.RuntimeTypeModelmodel = ChatSerializer.Create();

model.Serialize(stream, t);

bs = stream.ToArray();

}

return bs;

}

// 反序列化

public static TProtoRuntimeDeserialize<T>(byte[] bs)

{

T t = default(T);

using (System.IO.MemoryStream stream =new System.IO.MemoryStream(bs))

{

ProtoBuf.Meta.RuntimeTypeModelmodel = ChatSerializer.Create();

t = (T)model.Deserialize(stream,null, typeof(T));

}

return t;

}

现在,只需要简单调用这些函数就可以完成所有的序列化和反序列化工作了、。

ChatAPP.User user = new ChatAPP.User();

user.name = "用户甲";

user.chat = "hello,world";

// 序列化

byte[] bs =ProtoRuntimeSerialize<ChatAPP.User>(user);

ChatAPP.User user2;

// 反序列化

user2 =ProtoRuntimeDeserialize<ChatAPP.User>(bs);

Debug.Log(user2.name);

Protobuf除了可以应用到网络中,也可以应用到文件存储中,他的功能强大,是网络开发的利器,值得使用。

完毕!

在unity中双击启动(是Unity的项目路径了) 与 在文件夹中的双击启动(正常的) 是不一样的。

??

版权声明:本文为博主原创文章,未经博主允许不得转载。出自 游戏开发实验室_孙广东

时间: 2024-08-10 02:10:06

Unity 的ProtoBuff 相关批处理的相关文章

USB控制相关批处理

查询注册表是否禁用USB @echo off set "str=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\USBSTOR" for /f "tokens=2*" %%a in ('reg query "%str%" /v Start 2^>nul') do set "a=%%b" if "%a%"=="0x4" ( e

unity与手机相关吧

转载请注明出处:http://blog.csdn.net/u010019717 更全的内容请看我的游戏蛮牛地址:http://www.unitymanual.com/space-uid-18602.html ?? Windows Phone Application and Store Image,Icon Sizes  Application Image Sizes FlipCycleTileLarge -> 691×336 FlipCycleTileMedium -> 336×336 Fli

Unity编辑器扩展相关知识

1.一些类 1.1.GUI 界面 1.2.GUILayout 界面布局 1.3.GUIStyle 界面样式 1.4.GUIContent 界面内容 1.5.Editor 编辑器 1.6.EditorUtility 编辑器工具 1.7.EditorWindow 编辑器窗口 1.8.EditorGUI 编辑器界面 1.9.EditorGUILayout 编辑器界面布局 1.10.EditorGUIUtility 编辑器界面工具 1.11.Handles 控制柄 1.12.HandleUtility

【Unity】bundleID相关介绍

写在前面 在用Unity打包的时候,常听到bundleID这个名字,这里总结一些关于它的知识. 使用工具 Unity2017.2.1 介绍 bundleID,也有人叫它packageName,applicationID bundleID用 com.CompanyName.ProductName 格式起名 bundleID在代码里就是PlayerSettings.applicationIdentifier bundleID在Unity的PlayerSetting这里可以找到(以下两图是不同平台)

[转] Draw Call未被批处理?告诉你在Unity 5.6中如何查找原因 [复制链接]

Unity在5.6之前的版本中并未提供很直接的方式来查找Draw Call未被批处理的原因,但Unity 5.6在Frame Debugger中新增了一项功能,帮助开发者查找相关信息.今天这篇文章就为大家分享,在Unity 5.6中如何查看Draw Call未被批处理的原因. 相信大家都知道,Unity内置的动态与静态批处理有助于减少游戏中的Draw Call数量.在Stats窗口中,当"Saved by batching"值大于零时就表示批处理已经生效.但不幸的是,要想知道批处理为何

【Unity技巧】Unity中的优化技术

写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得的~Digital Tutors是一个非常棒的教程网站,包含了多媒体领域很多方面的资料,非常酷!除此之外,还参考了Unity Cookie中的一个教程.还有很多其他参考在下面的链接中. 这篇文章旨在简要地说明一下常见的各种优化策略.不过对每个基础有非常深入地讲解,需要的童鞋可以自行去相关资料. 还有一些我认为非常好的参考文章: Performance Optimization for Mobile Devices

(转)【Unity技巧】Unity中的优化技术

写在前面 这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得的~Digital Tutors是一个非常棒的教程网站,包含了多媒体领域很多方面的资料,非常酷!除此之外,还参考了Unity Cookie中的一个教程.还有很多其他参考在下面的链接中. 这篇文章旨在简要地说明一下常见的各种优化策略.不过对每个基础有非常深入地讲解,需要的童鞋可以自行去相关资料. 还有一些我认为非常好的参考文章: Performance Optimization for Mobile Devices

[转载]Unity中T4M插件的中文教程

ps:原文出处:http://blog.csdn.net/tianmao111/article/details/46482963 T4M是什么?为什么要用它? 它是一个地形(Terrain)工具.它是一个Unity地形的替代工具,用于所有被3D开发工具(Maya,EarthSculpto,3DS Max,Blender等)创建的几何体.最初,它只用于移动设备,但是更多的人发现了其他的一些益处: T4M是允许用户导入几何体到Unity作为地形(Terrain)的一种工具.T4M for Web和f

Unity 几种优化建议

转: http://user.qzone.qq.com/289422269/blog/1453815561?ptlang=2052 最简单的优化建议: 1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU.2.如果你用U3D自带的SHADER,在表现不差的情况下选择Mobile或Unlit目录下的.它们更高效.3.尽可能共用材质.4.将不需要移动的物体设为Static,让引擎可以进行其批处理.5.尽可能不用灯光.6.动态灯光更加不要了