unity遊戲開發之ULua框架介紹(一)
1.基礎介紹
①ULua 整合開發環境叫做:SimpleFramework,SimpleFramework 分為NGUI 和UGUI兩個版本,區別是NGUI 版本的框架資源中含有NGUI 這個外掛。SimpleFramework 本身不是Unitypackage 格式,而是一個Unity3D的專案工程,可以用Unity 直接開啟。
②SimpleFramework 和ULua
SimpleFramework > ULua > Lua
ULua 是對原生Lua 環境進行了一次“包裝”,用於滿足Unity 環境下的熱更新需求。為了更方便的使用,於是又對ULua 進行“二次包裝”,包裝成了一個框架:SimpleFramework。
2. SimpleFramework框架資源結構
(1)六個根資料夾
①Examples:SimpleFramework 熱更新案例;
②Lua:SimpleFramework 框架自帶的Lua 原始碼檔案(我們自己寫的Lua 指令碼也是存放在Lua 資料夾中);
③NGUI:當你需用更高版本的NGUI 時,替換即可,否則不需要碰;
④Plugins:uLua 執行所依賴的底層庫檔案,不需要碰;
⑤Scripts:SimpleFramework 自帶的C#指令碼檔案;
⑥uLua:uLua 全部程式碼。
備註:uLua:④ ⑥ SimpleFramework:① ② ⑤ ngui:③
(2)框架自帶選單命令
Lua 選單:uLua 環境相關處理命令;
Game 選單:用於打包不同平臺的AssetBundle 檔案。
(3)框架使用步驟
Lua 選單-->Welcome Screen 該視窗展示了框架的使用步驟。
<1>Lua-->Gen Lua Wrap File [生成Wrap 檔案(必備操作)]
該命令用於生成“Lua 包裝檔案”,存放在uLua\Source\LuaWrap 目錄下。該資料夾下全部是C#指令碼,這些指令碼檔案的名稱特點是:指令碼名+ Wrap;
Wrap 檔案介紹:
該資料夾下的指令碼對Unity 內常用元件指令碼的二次包裝,Lua 環境執行後,會,把這些Wrap 檔案載入到Lua 執行環境(Lua 虛擬機器)中,最終的效果就是:Lua 呼叫Wrap 檔案,Wrap 檔案呼叫C#,來實現Lua 呼叫C#。生成Wrap 檔案的目的是為了提高Lua 的執行效率。
<2>Game-->Build xxxx [生成不同平臺的AssetBundle 資源(必備操作)]
Game-->Build Windows Resource 生成Windows 平臺下的AB 檔案。生成後的AB 會存放到StreamingAssets 資料夾下。在生成的過程中同時還會把Lua 資料夾下的所有指令碼拷貝到該目錄,存放到lua 資料夾下。
(4)Lua 資料夾結構分析
SimpleFramework 框架自帶的Lua 原始碼檔案。
①3rd:第三方的Lua 指令碼外掛;
②Common:公共Lua 檔案目錄;
③Controller:控制器目錄;
④Logic:管理器目錄;
⑤System:cstolua 的系統目錄;
⑥View:檢視層目錄。
3.uLua 資料夾結構
uLua是SimpleFramework 框架專案的核心,在Unity 環境下使用uLua可以實現Lua 指令碼與Unity 內C#指令碼的互動,通過Lua 指令碼來操作Unity3D內的各種遊戲元件。
①Core:uLua 核心;
②Docs:uLua 文件,其實就是LuaInterface 的PDF 使用文件;
③Editor:uLua 編輯器擴充套件(專案內所有的Editor 資料夾都是編輯器擴充套件資料夾,並不侷限於根目錄);
④Examples:uLua 自帶演示案例;
⑤Source:cstolua 核心目錄。
4.uLua 環境下的程式碼互動
(1)基礎介紹
大家都知道可以使用LuaInterface 專案中的兩個DLL 檔案來實現C#與Lua 的互動。而在uLua 環境下本質也是通過LuaInterface 來實現Lua 與C#語言互動的。但是uLua 對LuaInterface 進行了二次的封裝,所以在程式碼書寫上和原生的會稍有不同。
(2)C#程式碼中執行Lua 程式碼
LuaState lua = new LuaState();
lua.DoString("print('Hello World Monkey')");
說明:
<1>同樣需要在C#程式碼中引入LuaInterface;
<2>原生的Lua 解析器物件“Lua”被二次封裝成了“
<3>LuaState 類存在的位置是:uLua\Core\Lua.cs。
(3)Lua 程式碼中操作Unity 內的類[反射方式/ 原生方式]
演示:通過Lua 程式碼在Unity 環境內建立一個遊戲物體。
luanet.load_assembly('UnityEngine')
GameObject = luanet.import_type('UnityEngine.GameObject')
BoxCollider = luanet.import_type('UnityEngine.BoxCollider')
local player = GameObject('Monkey')
player:AddComponent(luanet.ctype(BoxCollider))
說明:
<1>這種方式就是我們提到的原生方式;
<2>luanet 已經被封裝到了LuaInterface 名稱空間內,所以我們可以在Lua程式碼中直接使用luanet 這個物件;
<3>在Lua 環境內操作C#中的類建立物件,不要寫new 關鍵字!!!
<4>在Lua 環境內操作C#中的類建立物件,訪問物件中的方法使用分號(:);
<5>這種“反射方式”在專案開發中並不常用,但是也有用武之地,真正大量使用的是下方的Wrap 方式。
(4)Lua 程式碼中操作Unity 內的類[Wrap 方式]
luanet.load_assembly('UnityEngine')
GameObject = UnityEngine.GameObject
BoxCollider = UnityEngine.BoxCollider
local player = GameObject('Monkey')
player:AddComponent(BoxCollider.GetClassType())
LuaScriptMgr lua = new LuaScriptMgr();
lua.Start();
說明:
<1>這種是在uLua 開發過程中最常用的方式,95%+情況都是使用這種方式;
<2>Wrap 方式實現Lua 呼叫C#,依賴的是之前生成的LuaWrap 檔案(也就是通過選單自動生成到uLua\Source\LuaWrap 下的指令碼檔案);
<3>當使用Wrap 方式時,執行Lua 程式碼需要使用LuaScriptMgr;
<4>需要把AppConst.cs 指令碼中的的DebugMode 修改為true。
5.包裝新的Wrap 指令碼
當我們用Lua 的Wrap 方式訪問Unity 中的元件指令碼,或者自己寫的指令碼的使用,如果這些指令碼沒有自動生成“xxxxWrap”,專案執行後,就會報錯。
比如Animator 指令碼,就沒有預設生成Wrap 格式的檔案。遇到這種情況,我們就需要往框架的Wrap 生成器中新增我們要處理的新的類。
步驟如下:
①找到uLua\Editor\WrapFile.cs 開啟該指令碼,
使用該格式進行新增:_GT(typeof(類名)) ;
②Lua-->Clear LuaBinder File + Wrap File 清空原有的Wrap 檔案;
③Lua-->Gen Lua Wrap Files 重新生成Wrap 檔案;
這樣就能看的新增的Wrap 指令碼檔案了。