將xls轉(zhuǎn)成protobuf供Unity使用的流程

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

通用流程圖

流程圖

通用流程圖簡(jiǎn)述

  1. 在python運(yùn)行時(shí)下,依賴proto組件、xlrd的組件,使用xls_deploy_tool.py處理Hello.xls,生成Hello.data數(shù)據(jù)文件、及其對(duì)應(yīng)的Hello.proto解釋類。
  2. 在windows系統(tǒng)下,使用protoc.exe,將proto解釋類轉(zhuǎn)成中間格式Hello.desc。
  3. 將中間格式Hello.desc用語(yǔ)言工具翻譯成其他語(yǔ)言解釋類比如c#解釋類Hello.cs。
  4. 游戲運(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)備步驟。

  1. 準(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
  2. 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 的文件注釋。
  3. 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#為例
  4. 將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代碼。
  5. 在Unity讀取data文件,并且用cs代碼解釋

注:不能使用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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容