ToLua學習筆記,執行bundle中的lua指令碼
ToLua框架支援直接讀取執行lua指令碼檔案,也支援讀取打包到.unity3d中的lua指令碼。另外ToLua還支援位元組碼方式讀取指令碼。
打包工具類Packager.cs中對指令碼的打包,選擇如下打包方式:
注意此部分經過我的修改。然後它會呼叫下邊部分:
上邊選擇了lua位元組碼方式,其實區別只是EncodeLuaFile函式會把lua指令碼編譯成可被luajit執行的格式檔案。此函式內容如下:
無論是否選擇位元組碼方式,最終生成的到臨時目錄Lua中的檔案都是.byte結尾的。
ToLua/Lua和Lua目錄下的指令碼會拷貝到Lua目錄下
我的工程目錄結構如下:
臨時目錄下的結構如下:
對lua指令碼的打包是把他們所在的資料夾打包,而不是每個lua檔案分別打包,所以在遍歷Lua目錄後,還需要把Lua目錄本身加入打包列表,因為它下邊也包含指令碼.
最終打包到StreamingAssets下的結構如下:
打包完資源後,BuildLuaFile()函式會生成一個luafiles檔案,到StreamingAssets/lua中,內容如下:
BuildLuaFile函式的內容如下:
這個檔案是用來幹啥的呢?我們看一下LuaManager.cs中的程式碼:
此程式碼經過了我的修改,它的目的是讀取luafiles中列出來的所有包含lua指令碼的.unity3d檔案,並加入到loader的字典中:
我們來看下LuaLoader.cs中的程式碼:
此程式碼經過了我的修改,注意上邊轉小寫的目的是因為之前打包的時候,所有資原始檔都被小寫化了。
這裡讀取了所有指令碼的bundle包,並組合了名稱,儲存到字典中,繼續看AddSearchBundle函式:
那什麼時候會使用到它們呢?我們來看LuaManager.cs中的呼叫:
繼續進入:
此處我也做了修改,增加了bundleName引數,為什麼增加這個引數後續會介紹。繼續進入ReadFile
我選擇了bundle方式,所以會執行下邊函式,那上邊的beZip是哪裡設定的呢?看下邊:
繼續進入ReadZipFile:
這裡是最關鍵的地方,只要是有luaState.DoFile的呼叫最終都會執行到這裡
這裡經過了我的修改,框架原來的程式碼只有fileName引數,而我們的資源包是以資料夾為單位的,所以想確定fileName(lua指令碼名)到底屬於哪個資源包是做不到的,
因此才會有原來的那種拼接字串的無奈寫法。
我這裡增加了bundleName引數,在直接呼叫時,可以找到資源包,注意zipMap.TryGetValue這行。
但其實這裡還有個問題,有的時候並不是主動呼叫DoFile才會到這個函式,比如初始化時,後續的子呼叫到達這裡,這個時候bundleName引數是null的,所以我也保留了
原來的那種拼接方式,只是稍作修改,符合我luafiles檔案中的檔名格式。這種方式能執行lua目錄下和lua/fileName目錄下的指令碼。
之前還有個地方執行時也會呼叫這裡:
ReadZipFile返回的是byte[],最終輸入到下邊執行:
這裡lua檔名也就是chunkName(塊名),最終由底層dll呼叫,此時執行例項便可看到main.lua的結果