在上一篇文章 Unity3D熱更新之LuaFramework篇[02]--用Lua建立本身的面板 中,我介紹了LuaFramework加載面板的方法,但這個方法並不適用於其它Prefab資源,在這套框架中非面板型資源的加載方法另有套路。html
一、建立一個預製體
打開上次使用的工程,打開Main場景,建立一個名爲ImgOrc的Image,圖片就選例子用的獸人頭像。在Assets/LuaFramework/CustomPrj目錄下新建一個Prefabs目錄,而後拖動ImgOrc到該目錄下作成預製體,如圖1-1c#
圖1-1 windows
二、將預製體打成AssetBundle包
打開Assets/ LuaFramework/Editor/Packager.cs文件(用VS或Mono Develop編輯器打開),找到HandleExampleBundle方法,添加對ImgOrc預製體的打包代碼,如圖1-2所示數組
圖1-2框架
打包代碼1 /// <summary> 2 /// 處理框架實例包 3 /// </summary> 4 static void HandleExampleBundle() { 5 string resPath = AppDataPath + "/" + AppConst.AssetDir + "/"; 6 if (!Directory.Exists(resPath)) Directory.CreateDirectory(resPath); 7 8 AddBuildMap("prompt" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/Examples/Builds/Prompt"); 9 AddBuildMap("message" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/Examples/Builds/Message"); 10 11 //打包咱們新加的FirstPanel預製體 12 AddBuildMap("first" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/CustomPrj/FirstTest"); 13 //打包咱們新加的ImgOrc預製體 14 AddBuildMap("prefabs" + AppConst.ExtName, "*.prefab", "Assets/LuaFramework/CustomPrj/Prefabs"); 15 16 AddBuildMap("prompt_asset" + AppConst.ExtName, "*.png", "Assets/LuaFramework/Examples/Textures/Prompt"); 17 AddBuildMap("shared_asset" + AppConst.ExtName, "*.png", "Assets/LuaFramework/Examples/Textures/Shared"); 18 }
這裏要對AddBuildMap方法的參數加以說明編輯器
- 第一個參數是包名,即打包後在StreamingAssets目錄中顯示的包的名稱,AppConst.ExtName是擴展名,框架默認爲".unity3d",能夠自行修改;
- 第三個參數是要打包的資源的目錄,暫且稱爲源目錄;
- 第二個參數是打包模式,以字符串形式過濾出要打包的文件名,好比這裏*.prefab就表示源目錄下的全部prefab文件。
之因此將ImgOrc預製體打包的包名定義爲prefabs而不是ImgOrc,是由於這個打包是針對整個目錄的而不是單個資源。爲了說明這一狀況,我會在CustomPrj/Prefabs目錄下再加一個預製體ButtonPrefab。見圖1-3ide
見圖1-3函數
此次不修改打包文件。工具
找到LuaFramework菜單,點擊Build Windows Resources菜單項,開始自動打包操做,中間無需干預。post
打包結束,查看StreamingAssets目錄,能看到與剛剛給定的包名相應的文件:prefabs.unity3d,見圖1-4
圖1-4
圖中紅框標識的還有一個名爲prefabs的文件,這是沒有顯示後綴(其實有後綴,在unity中未顯示),這個是prefabs.unity3d包的清單文件,在windows下打開看以看到其全名爲prefabs.unity.manifest。
用Notepad++打開這個清單文件,能夠看到在3七、38行列出一這個AB包包含的兩個資源:ButtonPrefab.prefab和ImgOrc.Prefab。見圖1-5:
圖1-5
此框架的資源打包方式就是這樣的,全部資源都須要在代碼中添加相應包名、過濾模式、目錄。遊戲開發前期和資源變更較大時,會頻繁改動這個腳本的內容,用起來並非很方便。
三、在代碼中加載預製體
資源包有了,如今須要在代碼中加載這個包。
打開FirstCtrl.lua文件,在FirstCtrl.OnCreate方法中添加讀取資源包的方法,見代碼:
--啓動事件--
function FirstCtrl.OnCreate(obj)
gameObject = obj;
message = gameObject:GetComponent('LuaBehaviour');
--加載prefabs.unity3d資源包
resMgr:LoadPrefab("prefabs.unity3d", {"ImgOrc"}, function (prefabs)
end);
endresMgr是框架封裝好的資源管理工具,LoadPrefab函數用來讀取資源包。第一個參數是包名,第二個參數是包裏的資源名(Prefab名稱),第三個參數是包讀取成功的回調,參數prefabs爲讀出來的資源。
..
繼續完成代碼,進行實例操做等操做,代碼以下:
1 --啓動事件-- 2 function FirstCtrl.OnCreate(obj) 3 gameObject = obj; 4 transform = obj.transform; 5 6 message = gameObject:GetComponent('LuaBehaviour'); 7 8 --加載prefabs.unity3d資源包 9 resMgr:LoadPrefab("prefabs.unity3d", {"ImgOrc"}, function (prefabs) 10 log(prefabs.Length); --輸出 1 11 log(prefabs[0].name) --輸出 ImgOrc 12 13 --加載獸人頭像到FirstPanel下 14 local go = newObject(prefabs[0]); --實例化 15 go.transform:SetParent(transform); --設置FirstPanel爲父對象 16 go.transform.localPosition = Vector3.zero; --設置初始位置 17 go.transform.localScale = Vector3.one; --設置縮放 18 19 end); 20 end說明點:
- 回調函數的參數prefabs是一個userdata類型的數據(userdata通常是C#中的部分引用類型在Lua中的表示),這裏猜想是一個數組,由於經過.Length能夠取到長度,能過[0]能取到第一個元素。
- newObject是框架封裝好的實例化函數,猜想本質就是c#中的GameObject.Instantiate方法。
- 設置父對象、位置、縮放這幾步操做和c#中的操做差很少。由於自己調用的就是c#中的方法,即transform的方法。
- FirstCtrl.lua文件中的gameObject,transform表明的就是FirstPanel面板及面板上transform組件,是在面板建立時(OnCreate方法前兩行)注入進來的。
代碼完成後,運行Unity,能看到ImgOrc已經加載到了FirstPanel對象下,見圖1-6
圖1-6
非Panel的預製體加載流程就是這樣,加載方法是參照例子的PromptCtrl.lua寫的。
resMgr中還有放多其它加載資源的方法,留待之後再探究。
在用c#寫代碼的時候,給Button添加監聽有兩種方法,一是將腳本綁在Button組件上,經過面板選擇腳本中的方法來添加作;二是在代碼中經過Button.onClick.AddListener方法添加。
那麼在Lua應該怎麼作呢?
仍是以FirstPanel爲例,給FirstPanel右上角添加一個關閉按鈕,應用預製體而後從新打包,
而後:
一、在FirstPanel.lua文件中引用按鈕
打開FirstPanel.lua文件,在InitPanel函數中添加查找按鈕的代碼:
--初始化面板-- function FirstPanel.InitPanel() --查找關閉按鈕 this.btnClose = transform:FindChild("CloseButton").gameObject; end
二、在FirstCtrl.lua文件中添加監聽
打開FirstCtrl.lua文件,找到OnCreate方法,而後經過FirstPanel所掛的LuaBehaviour腳原本添加監聽事件,見圖2-1
圖2-1
AddClick方法有兩個參數,第一個是按鈕自己(上一步才引用過的),第二個是點擊後的回調函數。
AddClick的具體實現能夠能夠在LuaBehaviour.cs中找到。
運行Unity,點擊關閉按鈕,能看到打印了指望中的日誌,見圖2-2
圖2-2
給按鈕添加監聽就是這麼簡單,不過裏邊還藏着一些坑,之後的文章再細講。
總結一點,用Lua作邏輯的話,全部UI元素的使用都須要先在相應的XxxPanel中引用 ,而後到XxxCtrl中添加事件,對於結構複雜的UI,作起來很是耗時間。
文中屢次操做了FirstCtrl.lua和FirstPanel.lua文件,爲了方便參閱,現將兩個腳本完整的貼出來:
FirstPanel1 local transform; 2 local gameObject; 3 4 FirstPanel = {}; 5 local this = FirstPanel; 6 7 --啓動事件-- 8 function FirstPanel.Awake(obj) 9 gameObject = obj; 10 transform = obj.transform; 11 12 this.InitPanel(); 13 logWarn("Awake lua--->>"..gameObject.name); 14 end 15 16 --初始化面板-- 17 function FirstPanel.InitPanel() 18 --查找關閉按鈕 19 this.btnClose = transform:FindChild("CloseButton").gameObject; 20 end 21 22 --單擊事件-- 23 function FirstPanel.OnDestroy() 24 logWarn("OnDestroy---->>>"); 25 end
FirstCtrl1 FirstCtrl = {}; 2 local this = FirstCtrl; 3 4 local behaviour; 5 local transform; 6 local gameObject; 7 8 --構建函數-- 9 function FirstCtrl.New() 10 logWarn("FirstCtrl.New--->>"); 11 return this; 12 end 13 14 function FirstCtrl.Awake() 15 logWarn("FirstCtrl.Awake--->>"); 16 panelMgr:CreatePanel('First', this.OnCreate); 17 end 18 19 --啓動事件-- 20 function FirstCtrl.OnCreate(obj) 21 gameObject = obj; 22 transform = obj.transform; 23 24 behaviour = gameObject:GetComponent('LuaBehaviour'); 25 behaviour:AddClick(FirstPanel.btnClose, function () 26 log("你點擊了關閉"); 27 end); 28 29 --加載prefabs.unity3d資源包 30 resMgr:LoadPrefab("prefabs.unity3d", {"ImgOrc"}, function (prefabs) 31 log(prefabs.Length); --輸出 1 32 log(prefabs[0].name) --輸出 ImgOrc 33 34 --加載獸人頭像到FirstPanel下 35 local go = newObject(prefabs[0]); --實例化 36 go.transform:SetParent(transform); --設置FirstPanel爲父對象 37 go.transform.localPosition = Vector3.zero; --設置初始位置 38 go.transform.localScale = Vector3.one; --設置縮放 39 40 end); 41 end 42 43 --單擊事件-- 44 function FirstCtrl.OnClick(go) 45 destroy(gameObject); 46 end 47 48 --關閉事件-- 49 function FirstCtrl.Close() 50 panelMgr:ClosePanel(CtrlNames.Message); 51 end
本次的介紹就到這裏。