2016更新:本文寫于2014。其中值得注意的是,建議默認(rèn)使用python編寫腳本,對(duì)跨平臺(tái)有好處。而并非下文即將提及的、還不那么好地,使用bat、shell來(lái)編寫。
通用流程圖

通用流程圖簡(jiǎn)述
- 在python運(yùn)行時(shí)下,依賴proto組件、xlrd的組件,使用xls_deploy_tool.py處理Hello.xls,生成Hello.data數(shù)據(jù)文件、及其對(duì)應(yīng)的Hello.proto解釋類。
- 在windows系統(tǒng)下,使用protoc.exe,將proto解釋類轉(zhuǎn)成中間格式Hello.desc。
- 將中間格式Hello.desc用語(yǔ)言工具翻譯成其他語(yǔ)言解釋類比如c#解釋類Hello.cs。
- 游戲運(yùn)行時(shí)引入protobuf的dll,使用c#解釋類對(duì)data數(shù)據(jù)文件進(jìn)行讀取。
Killer項(xiàng)目使用步驟
目錄解釋
- 配置軟件安裝目錄:KillerTool\DataConfigSetup。
- 配置表及工具目錄:KillerProject\DataConfigBuild:
- 配置表目錄:KillerProject\DataConfigBuild\DataConfig。所有xls都在這里。它們是從策劃SVN庫(kù)里的DataConfig外鏈到這里的
- 導(dǎo)出數(shù)據(jù)目錄:KillerProject\Assets\StreamingAssets\DataConfig
- 導(dǎo)出代碼目錄:KillerProject\Assets\Scripts\Killer\DataConfig\ProtoGen
環(huán)境準(zhǔn)備步驟
- 進(jìn)入配置軟件安裝目錄:KillerTool\DataConfigSetup
- 如果你的本地電腦沒(méi)安裝python及其組件
- 視乎你是32位還是64位操作系統(tǒng),安裝python-2.7.7.32.msi或python-2.7.7.amd64.msi。
- 把你剛剛選擇安裝python的路徑添加到本地環(huán)境變量的path中。如下圖環(huán)境變量path
- 命令行進(jìn)入目錄setuptools-5.1,執(zhí)行命令
python setup.py install - 命令行進(jìn)入protobuf-2.5.0\python目錄,執(zhí)行命令
python setup.py install - 命令行進(jìn)入xlrd-0.9.3目錄,執(zhí)行命令
python setup.py install
環(huán)境準(zhǔn)備步驟到此結(jié)束。
使用方法
- 如果你(一般是策劃同學(xué)或程序同學(xué))是修改已有xls文件,修改保存xls后,運(yùn)行xls_all.bat,并上傳導(dǎo)出數(shù)據(jù)目錄里受到修改的data文件
- 如果你(一般是程序同學(xué))是要添加新xls文件
- 在配置表目錄添加你的xls文件(注意xls文件頭格式需要符合格式)
- 修改xlsc_all.bat,新增一行
call xlsc.bat <表格文件名> <表格名>,比如call xlsc.bat gm GM_CONF - 修改后運(yùn)行xlsc_all.bat
- 上傳導(dǎo)出數(shù)據(jù)目錄里新增的data文件
- 上傳導(dǎo)出代碼目錄里新增的cs文件
- 修改導(dǎo)出代碼目錄里的DataConfigManager.cs文件,使用cs文件對(duì)對(duì)應(yīng)的data文件進(jìn)行讀取。方法可參考那里已有的代碼。
- 如果你(一般是程序同學(xué))要?jiǎng)h除已有xls文件
- 請(qǐng)刪除xlsc_all.bat中對(duì)應(yīng)的腳本代碼
- 請(qǐng)刪除導(dǎo)出數(shù)據(jù)目錄里對(duì)應(yīng)的data文件
- 請(qǐng)刪除導(dǎo)出代碼目錄里對(duì)應(yīng)的cs文件和DataConfigManager.cs里對(duì)應(yīng)的解釋代碼
通用項(xiàng)目準(zhǔn)備步驟
如果你準(zhǔn)備搭建新的項(xiàng)目環(huán)境,或者對(duì)環(huán)境準(zhǔn)備的方法感興趣,可繼續(xù)閱讀下面的通用項(xiàng)目準(zhǔn)備步驟。
- 準(zhǔn)備xls_deploy_tool.py工具環(huán)境。xls_deploy_tool.py是一個(gè)python腳本,運(yùn)行在python環(huán)境,并且python要安裝了proto組件和xlrd組件
- 安裝python運(yùn)行時(shí)
- 在python官網(wǎng)下載并安裝python2.7(不能裝最新的python3,因?yàn)閜ython3不向下兼容,而protobuff是用python2的)。
- 把你剛剛選擇安裝python的路徑添加到本地環(huán)境變量的path中。如下圖環(huán)境變量path
- 安裝setuptool
- python安裝protobuff之前,需要先安裝setuptool。setuptool類似于python的一個(gè)組件安裝管理器
- 在setuptool官網(wǎng)的最下面點(diǎn)擊下載安裝文件,這里我們可以安裝setuptools-5.1.zip。解壓它。
- 用命令行進(jìn)入剛解壓的setuptool目錄,執(zhí)行命令
python setup.py install
- 安裝protobuff
- 我們目前使用2.5.0的protobuff版本
- 在protobuff官網(wǎng)下載protobuff的“全文件壓縮包”(protobuf-2.5.0.tar.bz2)和“編譯器壓縮包”(protoc-2.5.0-win32.zip)
- 將“全文件壓縮包”解壓
- 在里面創(chuàng)建compiler文件夾,即protobuf-2.5.0\python\google\protobuf\compiler
- 將“編譯器壓縮包”里的protoc.exe拷到protobuf-2.5.0\src
- 用命令行進(jìn)入剛解壓的protobuf\python目錄,執(zhí)行命令
python setup.py install
- 安裝xlrd(xls reader)
- 在xlrd官網(wǎng)下載并解壓
- 用命令行進(jìn)入剛解壓的xlrd目錄,執(zhí)行命令
python setup.py install
- 安裝python運(yùn)行時(shí)
- xls_deploy_tool.py
- xls_deploy_tool.py是騰訊魔方工作室jameyli同學(xué)的作品
- 使用方法是在命令行鍵入如下命令
python xls_deploy_tool.py <表格名> <xls文件名>
- 它將“符合格式”的xls文件生成data文件和proto文件
-
“符合格式”指的是要求xls的每一列的前4行用于定義數(shù)據(jù)格式。例子如圖:
- 詳細(xì)格式文檔可參考xls_deploy_tool.py 的文件注釋。
- xls_deploy_tool.py生成的文件
- 生成的data文件是最終在游戲內(nèi)進(jìn)行讀取的數(shù)據(jù)文件,以protobuff定義的格式進(jìn)行壓縮存儲(chǔ)(或者明文存儲(chǔ),但xls_deploy_tool.py暫時(shí)只實(shí)現(xiàn)了壓縮存儲(chǔ))
- 生成的proto文件是用于解釋上面這個(gè)data文件的解釋類。
- 但由于我們需要在我們游戲內(nèi)對(duì)其進(jìn)行讀取,而游戲往往只能運(yùn)行其他高級(jí)語(yǔ)言,所以需要將proto翻譯成對(duì)應(yīng)的語(yǔ)言
- 這里以C#為例
- 將proto語(yǔ)言翻譯成C#語(yǔ)言
- 需要分兩步走:
- 使用“編譯器壓縮包”(比如protoc-2.5.0-win32.zip)的protoc.exe將proto解釋成“FileDescriptorSet ”中間格式
- 使用protobuf-net的protogen.exe將“FileDescriptorSet ”翻譯成cs文件
- protoc.exe
- 使用先前“編譯器壓縮包”(protoc-2.5.0-win32.zip)里的protoc.exe,命令行命令大概是
- protogen.exe
- 下載、解壓protobuf-net
- ProtoGen目錄都需要用到,其中的protogen.exe負(fù)責(zé)將proto文件翻譯成cs代碼。
- 需要分兩步走:
- 在Unity讀取data文件,并且用cs代碼解釋
- 到protobuf-net的github網(wǎng)站,下載工程的zip包,解壓,把里面的protobuf-net文件夾放置在Unity工程的Assets\Plugins目錄下
注:不能使用protobuf-net\Full\unity\下的protobuf-net.dll拷到Unity工程的Assets\Plugins目錄下的方法。
因?yàn)椴渴鸬絠OS設(shè)備,會(huì)發(fā)生JIT錯(cuò)誤(ExecutionEngineException: Attempting to JIT compile method)。原因是因?yàn)閕OS不允許JIT(Just In Time),只允許AOT(Ahead Of Time)。
解決這個(gè)問(wèn)題的方法之一是使用protobuf-net的precompile工具,但研究發(fā)現(xiàn),過(guò)程會(huì)比較麻煩。具體可參閱precompile的help命令,或者谷歌“precompile protobuf net”。
解決這個(gè)問(wèn)題的方法之二,也是比較簡(jiǎn)單、證明過(guò)可行的,就是直接把源代碼代替protobuf-net.dll,拷到Unity工程的Assets\Plugins目錄下。
由于編譯protobuf-net代碼需要unsafe編譯,所以還需要在Assets文件夾放入“smcs.rsp”文件,里面加入一行-unsafe作為編譯參數(shù)。
- 引用導(dǎo)出的cs類,using ProtoBuf的命名空間,使用Serailizer.Deserialize<T>()全局函數(shù),進(jìn)行數(shù)據(jù)的解釋,關(guān)鍵代碼如下
private T ReadOneDataConfig<T>(string FileName)
{
FileStream fileStream;
fileStream = GetDataFileStream(FileName);
if (null != fileStream)
{
T t = Serializer.Deserialize<T>(fileStream);
fileStream.Close();
return t;
}
return default(T);
}
private FileStream GetDataFileStream(string fileName)
{
string filePath = GetDataConfigPath(fileName);
if (File.Exists(filePath))
{
FileStream fileStream = new FileStream(filePath, FileMode.Open);
return fileStream;
}
return null;
}
private string GetDataConfigPath(string fileName)
{
return Application.streamingAssetsPath + "/DataConfig/" + fileName + ".data";
}
附Killer的bat文件
@echo off
set XLS_NAME=%1
set SHEET_NAME=%2
set DATA_DEST=%3
echo.
echo =========Compilation of %XLS_NAME%.xls=========
::---------------------------------------------------
::第一步,將xls經(jīng)過(guò)xls_deploy_tool轉(zhuǎn)成data和proto
::---------------------------------------------------
set STEP1_XLS2PROTO_PATH=step1_xls2proto
@echo on
cd %STEP1_XLS2PROTO_PATH%
@echo off
echo TRY TO DELETE TEMP FILES:
del *_pb2.py
del *_pb2.pyc
del *.proto
del *.data
del *.log
del *.txt
@echo on
python xls_deploy_tool.py %SHEET_NAME% ..\DataConfig\%XLS_NAME%.xls
::---------------------------------------------------
::第二步:把proto翻譯成cs
::---------------------------------------------------
cd ..
set STEP2_PROTO2CS_PATH=.\step2_proto2cs
set PROTO_DESC=proto.protodesc
set SRC_OUT=..\src
cd %STEP2_PROTO2CS_PATH%
@echo off
echo TRY TO DELETE TEMP FILES:
del *.cs
del *.protodesc
del *.txt
@echo on
dir ..\%STEP1_XLS2PROTO_PATH%\*.proto /b > protolist.txt
@echo on
for /f "delims=." %%i in (protolist.txt) do protoc --descriptor_set_out=%PROTO_DESC% --proto_path=..\%STEP1_XLS2PROTO_PATH% ..\%STEP1_XLS2PROTO_PATH%\*.proto
for /f "delims=." %%i in (protolist.txt) do ProtoGen\protogen -i:%PROTO_DESC% -o:%%i.cs
cd ..
::---------------------------------------------------
::第三步:將data和cs拷到Assets里
::---------------------------------------------------
@echo off
set OUT_PATH=..\Assets
set DATA_DEST=StreamingAssets\DataConfig
set CS_DEST=Scripts\Killer\DataConfig\ProtoGen
@echo on
copy %STEP1_XLS2PROTO_PATH%\*.data %OUT_PATH%\%DATA_DEST%
copy %STEP2_PROTO2CS_PATH%\*.cs %OUT_PATH%\%CS_DEST%
::---------------------------------------------------
::第四步:清除中間文件
::---------------------------------------------------
@echo off
echo TRY TO DELETE TEMP FILES:
cd %STEP1_XLS2PROTO_PATH%
del *_pb2.py
del *_pb2.pyc
del *.proto
del *.data
del *.log
del *.txt
cd ..
cd %STEP2_PROTO2CS_PATH%
del *.cs
del *.protodesc
del *.txt
cd ..
::---------------------------------------------------
::第五步:結(jié)束
::---------------------------------------------------
cd ..
@echo on
附protoc.exe的參數(shù)文檔:
E:\Project\ied_kl_rep\client_proj\trunk\KillerProject\DataConfigBuild\step2_prot
o2cs>protoc --help
Usage: protoc [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
-IPATH, --proto_path=PATH Specify the directory in which to search for
imports. May be specified multiple times;
directories will be searched in order. If not
given, the current working directory is used.
--version Show version info and exit.
-h, --help Show this text and exit.
--encode=MESSAGE_TYPE Read a text-format message of the given type
from standard input and write it in binary
to standard output. The message type must
be defined in PROTO_FILES or their imports.
--decode=MESSAGE_TYPE Read a binary message of the given type from
standard input and write it in text format
to standard output. The message type must
be defined in PROTO_FILES or their imports.
--decode_raw Read an arbitrary protocol message from
standard input and write the raw tag/value
pairs in text format to standard output. No
PROTO_FILES should be given when using this
flag.
-oFILE, Writes a FileDescriptorSet (a protocol buffer,
--descriptor_set_out=FILE defined in descriptor.proto) containing all of
the input files to FILE.
--include_imports When using --descriptor_set_out, also include
all dependencies of the input files in the
set, so that the set is self-contained.
--include_source_info When using --descriptor_set_out, do not strip
SourceCodeInfo from the FileDescriptorProto.
This results in vastly larger descriptors that
include information about the original
location of each decl in the source file as
well as surrounding comments.
--error_format=FORMAT Set the format in which to print errors.
FORMAT may be 'gcc' (the default) or 'msvs'
(Microsoft Visual Studio format).
--plugin=EXECUTABLE Specifies a plugin executable to use.
Normally, protoc searches the PATH for
plugins, but you may specify additional
executables not in the path using this flag.
Additionally, EXECUTABLE may be of the form
NAME=PATH, in which case the given plugin name
is mapped to the given executable even if
the executable's own name differs.
--cpp_out=OUT_DIR Generate C++ header and source.
--java_out=OUT_DIR Generate Java source file.
--python_out=OUT_DIR Generate Python source file.
附protogen.exe參數(shù)列表
E:\Project\ied_kl_rep\client_proj\trunk\KillerProject\DataConfigBuild\step2_prot
o2cs\ProtoGen>protogen.exe --help
protobuf-net:protogen - code generator for .proto
usage: protogen -i:{infile2} [-i:{infile2}] [-o:{outfile}] [-t:{template}] [-p:{
prop}[=value]] [-q] [-d]
-i: Input file(s); proto definitions, either as text or pre-compiled binary (via
protoc)
-o: Output file; if none specified, writes to stdout
-t: Template to use; defaults to csharp
-p: Property for the template; value defaults to true; use -p:help to view avail
able options
-q: Quiet; suppresses header
-d: Include all dependencies of the input files in the set so the set is self-co
ntained.
-ns: Default namespace; used in code generation when no package is specified
Examples:
protogen -i:input.proto -o:output.cs
protogen -i:input.proto -o:output.xml -t:xml
protogen -i:input.proto -o:output.cs -p:datacontract -q
protogen -i:input.proto -o:output.cs -p:observable=true

