Unity3D根據(jù)Prefab自動生成UI類,并自動關(guān)聯(lián)變量和控件

原文?http://www.kidsang.com/archives/741

? ? ?在制作UI界面的時候,我們需要獲取界面上的UI控件,以實現(xiàn)對UI界面的控制。比如,獲取文本框控件來輸入文字,或者獲取按鈕控件注冊事件回調(diào)。對于Unity3D來說,我們有兩種方式把某個控件關(guān)聯(lián)到某變量上。

靜態(tài)關(guān)聯(lián):在類中暴露public變量給編輯器,然后在編輯器中通過拖拽控件的方法把變量和控件關(guān)聯(lián)上。

動態(tài)關(guān)聯(lián):從UI界面的根節(jié)點(diǎn)開始向下遍歷,一直找到自己想要的控件。

如果可能的話,當(dāng)然最好是使用靜態(tài)關(guān)聯(lián)。這種方法不需要在游戲運(yùn)行時查找控件,效率高于動態(tài)關(guān)聯(lián),因此能提高界面的加載速度。然而這種方式的痛苦之處在于,我們需要手動為每個界面編寫對應(yīng)的類文件,暴露變量,并手動在編輯器中拖拽控件賦予變量??紤]到每個游戲都會有巨量的界面,能否使用自動的方式生成對應(yīng)的UI類文件,并自動關(guān)聯(lián)變量呢?這樣將會給界面開發(fā)提供巨大的便利,省去很多繁瑣的事。

第一步,根據(jù)Prefab生成UI類

這一步非常簡單,我們可以通過寫一個Editor腳本來完成這個工作:

實例化Prefab到場景

便利實例化后的GameObject,把所有含有UI控件的GameObject找出來,將他們的名字記錄下來

根據(jù)第2步記錄的信息生成UI類cs文件,保存。

把Prefab的InstanceID,和第2步中記錄的信息,以文本的形式保存為一個臨時文件。

為什么會有第4步的操作呢?這是為了給后續(xù)的操作用的。

第二步,關(guān)聯(lián)UI類中的變量和Prefab中的控件

這一步需要一些技巧。因為UI的類文件是我們剛剛生成的,尚未編譯,因此我們無法立刻通過GameObject.AddComponent()的方式將其添加到Prefab上。我曾經(jīng)嘗試過C#的反射機(jī)制立刻編譯新生成的UI類文件,并動態(tài)獲取類型,強(qiáng)行調(diào)用GameObject.AddComponent()將其加到Prefab上。然而,這種方式編譯出來的類信息處于另外一個Assembly 中(而不是Assembly-CSharp.dll),在編輯器中Prefab會顯示缺失類文件引用(script file missing)。顯然,我們需要讓Unity編輯器來編譯我們生成的文件,并等待它編譯完成后再執(zhí)行后續(xù)操作。

幸好,Unity編輯器提供了對應(yīng)的接口。首先,我們可以通過調(diào)用AssetDatabase.ImportAsset()AssetDatabase.Refresh()觸發(fā)編輯器編譯代碼。然后,我們可以在Editor腳本中通過[UnityEditor.Callbacks.DidReloadScripts]屬性監(jiān)聽編譯完成事件。

由于Unity編輯器編譯完成后,會重載所有的DLL,所有內(nèi)存中的變量都會被清除。因此,我們只能文件的方式傳遞信息。在第一步的第4小步中,我們已經(jīng)把必要的信息保存成臨時文件,我們只需要讀取這個文件就能拿回我們想要的信息。

綜上所述,步驟如下:

監(jiān)聽[UnityEditor.Callbacks.DidReloadScripts]事件,等待編譯完成。

讀取臨時文件,獲取Prefab的名稱和InstanceID。

使用InstanceID獲取我們的Prefab。 GameObject uiGameObject =?EditorUtility.InstanceIDToObject(instanceID) as GameObject;

獲取我們游戲的Assembly ,并從中獲取剛編譯好的類。 Type myUIClass = typeof(AClassInMyGame).Assembly.GetType(“MyUIClass”);

使用GameObject.AddComponent()將UI類添加到Prefab上。 MyUIClass myUI = uiGameObject.AddComponent(myUIClass);

讀取臨時文件,獲取導(dǎo)出的控件信息和名稱,使用FieldInfo.SetValue()將控件賦予UI類中的變量。?MyUIClass.GetField(‘SomeVariable’).SetValue(myUI, uiControl)

保存Prefab,所有的控件和變量已成功關(guān)聯(lián)。

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

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

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