Unity3D熱更新之LuaFramework篇[03]--prefab加載和Button事件

在上一篇文章 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);
end

 resMgr是框架封裝好的資源管理工具,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

 說明點:

  1. 回調函數的參數prefabs是一個userdata類型的數據(userdata通常是C#中的部分引用類型在Lua中的表示),這裏猜想是一個數組,由於經過.Length能夠取到長度,能過[0]能取到第一個元素。
  2. newObject是框架封裝好的實例化函數,猜想本質就是c#中的GameObject.Instantiate方法。
  3. 設置父對象、位置、縮放這幾步操做和c#中的操做差很少。由於自己調用的就是c#中的方法,即transform的方法。
  4. 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文件,爲了方便參閱,現將兩個腳本完整的貼出來:

 1 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
FirstPanel

 

 1 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
FirstCtrl

 

 

本次的介紹就到這裏。

相關文章
相關標籤/搜索