【Unity】protobuf故意踩坑记
写在前面
- 起因:我看到工作项目使用protobuf来做序列化时脑子冒出许多问号,“以前我按《Unity3D网络游戏实战》做坦克游戏时为了让客户端和服务器使用统一协议用到了protobuf,怎么没有啥序列化的印象?”,“为什么非得选protobuf而不是其他工具?”,“序列化时常看到的MemoryStream和FileStream,以及StreamWriter、StreamReader这些到底是什么关系?”等等等等,于是我决定在自己的测试项目上从头开始摸索protobuf,以能成功用上protobuf为最终目标,顺便解决我这一系列问题。
- 本篇博文主要记录我用头开始使用protobuf遇到的种种状况和问题解答,重点在踩坑而非如何使用protobuf。如何使用protobuf部分这里可以概括为:其实项目使用的是protobuf-net而非protobuf,从该谷歌网页下载protobuf-net r668压缩包,解压文件后使用里面的protobuf-net.dll和protogen.exe。
- 本篇博文按“我的问题是什么”——>“解决问题过程记录”来组织。
- Unity版本:2017.4.39f1
踩坑
- protobuf是什么?——> 我先去翻了翻官网,官网首页说它是一个“无关语言无关平台且可扩展的序列化工具”,但这简单一句话并不能让我体会它的好,于是我去翻了翻博客们但也没找到更具体一点的解释,最后我还是回到了官网找到了具体解释(在官网Guides - Tutorials - Why use protocol buffers?),简单来说:它以我们会想到的几种序列化实现方法举例说明有哪些麻烦,而protobuf搞定了这些麻烦。
- 为什么非得选protobuf而不是其他工具?——> 在主程的博客上,我看到了他选protobuf的原因,简单来说:他考虑过Unity自带的scriptObject和挂脚本,但该方法不支持热更;考虑过Xml,但它不支持Unity一些属性(如Color)序列化,而且影响重构(例如重构时改变量名是很常见的一件事),所以最后选用protobuf。
- 怎么用protobuf序列化?——> (这里开始我在个人测试项目上操作,遇到状况颇多)
- 我看了官网Tutorials,再看了它Github首页上的readme,它要安两个东西,一个是编译器protoc(其实最后要用的是protoc.exe),它负责把.proto文件生成对应.cs文件;另一个是dll,它负责代码实际功能(编码解码、序列化等)。但项目里用的不是谷歌官方的,而是第三方工具protobuf-net(当然它也是基于protobuf做的)。
- 翻到的博客很多都没写到我关注的重点,有的把protobuf-net和protobuf混为一谈,有的不介绍为什么用protobuf-net而不是protobuf,而且protobuf安装说明总得有参考官方英文说明吧,也没列出参考,就直接讲如何安装了。
- 我的项目Unity版本是2017.4.39f1,它用的是.net 3.5(如下图),但protobuf不支持.net 3.5(这在它Github上源码的readme文档里解释得很清楚,不过最开始我还是狂搜别人博客才知道大家不用官方protobuf的原因是这样),所以大家才选择了使用protobuf-net。
- protobuf-net的Github上的What Files Do I Need文档里说,我会用到的是它的dll和protogen工具,因为我想直接拿到dll,所以直接在源码文件夹里搜protobuf-net.dll,发现有很多protobuf-net.dll都放在assorted文件夹下,而看这个文件夹的readme上作者说这个文件夹什么杂项啥都有。到底用哪个dll呢?作者的文件夹结构把我绕晕了……
- 参考这篇博文,我打算编protobuf-net源码来得到它的dll,但工程用VS2015打开会有XML报错,放弃这个安装方向,转而参考这篇博文用NuGet来安装,发现protobuf-net最新版(此时最新版为3.0.62,它需要.net4.6.1).net版本比Unity要求高,而这里能支持.net3.5的protobuf-net最高版本就是2.4.6。
NuGet帮我下在这了,但我并不知道哪些文件夹内容需要放Unity,这里也并没有protogen工具……
于是我想去Github下源码看看能不能解决问题,我回到protobuf-net的Github上,用view all tag跳到release面板,查到能下的竟是2.4.5版本(它也没有日志说明支持.net版本)
点击release查看所有版本
把2.4.5版本源码下载后,再打开工程仍有xml报错,查了解决方法要么在VS2015里一个个改错要么用VS2017,我决定去用VS2017。用VS2017后打开工程发现又有.net版本问题,我试图下了对应.net的SDK来解决但搞不定!于是回到前面NuGet下载protobuf-net2.4.6那步,这里的protobuf-net.dll我用的是net35文件夹里的dll,在Unity的Plugins文件夹下新建一个名为protobuf-net文件夹,将dll放入。我也试过放高于.net35版本的dll,显然在Unity里点dll时会看到报错。

虽然NuGet可以帮下protobuf-net.dll,但protogen工具到底从哪里找呢?我试过用DotNetTool命令行工具下了从高到低好几个版本的protogen,但即使是NuGet上最低版本1.0.6的protogen它生成的.cs脚本放Unity里仍会有语法报错(用了C#6内容,当前Unity是C#4.0),而语法报错解决方法是Unity要升到.net4.6才行……
我试过用G站上的protobuf-net2.4.5里的protogen工程生成protogen工具,也仍有语法报错。最后参考这个博文,我还是回到谷歌网页下了protobuf-net r668版本,直接用里面的protogen.exe(这里我也试过用G站上的protobuf-net r668源码生成protogen.exe,这次生成竟然成功了!)
虽然之前我用NuGet下的protobuf-net2.4.6版本的protobuf-net.dll放Unity里没问题,但为了配合protobuf-netr668版本,最后还是用protobuf-netr668文件夹里的protobuf-net.dll。
- 总的来说,我从谷歌网页下载protobuf-net r668,使用了里面的protobuf-net.dll和protogen.exe。
- 在protogen.exe文件夹下随便建个.bat文件,内容如下图这么写,然后运行该bat,就能看到protogen使用帮助。
- 总的来说,我从谷歌网页下载protobuf-net r668,使用了里面的protobuf-net.dll和protogen.exe。
protogen帮助说明
下图是执行protogen正确写法示例:

- protobuf-net安好了,怎么用它的序列化呢?——> 说明就在protobuf-net的Github首页上,特性很少,使用极其简单。
- 序列化时常看到的MemoryStream和FileStream,以及StreamWriter、StreamReader这些到底是什么关系?——>
- 对于Stream,《深入理解C#》和《C#图解教程》、《CLR via C#》都没有讲,连基本IO读写都没讲。
- 资料来自《精通C#》,以下内容是我的概括:
- File和FileInfo关系:两者用哪个都行,不过用File能省更多代码,而用FileInfo会能得到更多文件信息。同理Directory和DirectoryInfo。
- FileStream只能处理byte(读byte写byte),当然文档里仍然是正常显示(内容是什么显示就是什么)。
- StreamWriter、StreamReader基于字符操作,就是用来WriteLine(…)这些,StringWriter意思差不多,只是和StreamWriter内部细节不太一样。
- BinaryWriter基于二进制操作,文档里是二进制(就是看上去是乱码)。
- 最后书上没讲MemoryStream内存流,只提了一句要保存为文件就用FileStream,放内存就用MemoryStream……我在msdn上查了MemoryStream,它说序列化用它性能更好,我在谷歌上没搜到“使用MemoryStream性能更好”的好举例。
- 以前我按《Unity3D网络游戏实战》做坦克游戏时为了让客户端和服务器使用统一协议用到了protobuf,怎么没有啥序列化的印象?——>我回头去看书和做的工程了,它实际上用的就是protobuf-net工具,协议就是编码(序列化)后才收发的。书作者简单介绍了两句protobuf和protobuf-net的关系,直接给了protobuf-net的dll和protogen。
【Unity】protobuf故意踩坑记的更多相关文章
- Unity接入AbMob踩坑记
之前是配置好的环境,不知道怎么突然就不正常了. 一直弹出下面的报错: Error running CocoaPods. Please ensure you have at least version ...
- Unity打包IOS踩坑记
1. Xcode不显示模拟器 之前一直用真机调试,就没注意模拟器.今天要上传版本要用到模拟器截图,发现竟然Xcode的运行选项竟然没有显示模拟器. 也是网上找了各种方法,修改各种设置,清了各种文件夹都 ...
- Hook踩坑记:React Hook react-unity-webgl
自公司前后分离上手React以来,一个坑一个坑的踩,Class的全生命周期云里雾里,还么屡明白,就抱上了Hook的大腿不松手,确实爽到飞起.修改到Hook的过程基本比较顺畅,直接少了三分之一的代码,组 ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 【踩坑记】从HybridApp到ReactNative
前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
随机推荐
- crontab计划运行shell脚本,调用ncl执行失败
编写了bash脚本,调用ncl脚本绘图,在前台运行时候无误,但是加入crontab任务就是始终无法出图,并且无错误输出. 经过搜索,问题得到解决.是环境变量的问题.所有执行的命令,和文件都要指定完整的 ...
- STP协议-基础
生成树协议 一 .技术背景一个缺乏冗余性设计的网络:任何一个网络节点出现故障,会造成单链路故障.单设备故障,使整个网络瘫痪. 引入冗余性的同时也引入了二层环路:网络的冗余性增强了,但是却出现了二层环路 ...
- 《Vue.js 3.x高效前端开发(视频教学版)》简介
#好书推荐##好书奇遇季#<Vue.js 3.x高效前端开发(视频教学版)>,京东当当天猫都有发售.本书配套示例源码.PPT课件.思维导图.数据集.开发环境与答疑服务. 本书通过对Vue. ...
- /usr/bin/install: cannot create regular file `/usr/local/jpeg6/include/jconfig.h'
出现下列异常: /usr/bin/install -c -m 644 jconfig.h /usr/local/jpeg6/include/jconfig.h /usr/bin/install: ca ...
- CSC落榜
2021年5月31日21:00点,CSC公布结果,未通过.看到这,我感觉空气瞬间凝固,窒息,那一瞬间我无比平静,我以为我会哭,但是,却泣不成声,脑中第一时间想到得是,如何面对认识得人,全世界感觉都知道 ...
- springboot配置文件中的基本配置
#应用启动端口设置server.port=9088#=================================微信相关====================================# ...
- 像MIUI一样做Zabbix二次开发(2)——Zabbix与商业及开源产品的比较分析
Zabbix的特点 Zabbix是一个基于WEB界面的提供分布式系统监控的开源解决方案,通过浏览器监视,做到告警分级处理.网络访问安全可控,该开源平台在全球有广泛的用户基础,他的特点: 开放性:源代码 ...
- 利用 fastjson 的 toJSONStringWithDateFormat 方法,将Date 格式化 为常见类型的时间
利用 fastjson 的 toJSONStringWithDateFormat 方法,将Date 格式化 为常见类型的时间 JSON.toJSONStringWithDateFormat(nrcSt ...
- fiddler抓包返回304
为了验证部分场景需要对接口返回数据进行修改后验证前端代码逻辑处理,发现同一域名下其他接口都正常返回,但是某个端口返回304. 操作步骤是页面打开后接口已经请求了,这时候才打开fiddler抓取请求拦截 ...
- NAT的转换
NAT的转换 拓扑图 Sever0的IP地址:192.168.0.1/24 网关:192.168.0.254 PC0的IP地址:192.168.0.100/24 PC1的IP地址:192.168.0. ...