UI框架設(shè)計(jì)
UI框架是我們經(jīng)常在項(xiàng)目開發(fā)中需要解決的一個(gè)問題,面試也經(jīng)常被問道。很多框架設(shè)計(jì)的新人甚至有一些有相當(dāng)豐富經(jīng)驗(yàn)的開發(fā)者把這個(gè)問題想的過于復(fù)雜,我們就從需求開始分析,來解決UI框架的設(shè)計(jì)問題,設(shè)計(jì)出來一個(gè)足夠簡單又足夠好用的UI框架。一個(gè)好用的UI框架要做到以下幾點(diǎn)原則:
(1) UI視圖與UI的代碼進(jìn)行完全的分離。UI代碼操作與控制UI視圖中的節(jié)點(diǎn)來顯示結(jié)果與接收來自用戶的操作。
(2)代碼與視圖分離后,要提供一種方法,非常方便的能將結(jié)果更新到UI視圖上;
(3)代碼與視圖分離后,需要提供一些方法,可以在代碼中封裝監(jiān)聽事件的接口,讓監(jiān)聽事件更方便。
以上3條原則確定后,大的機(jī)制就確定了,一個(gè)界面視圖+界面控制代碼,提供接口與方式非常方便的能操作視圖。
?
很多UI框架的同學(xué),還要設(shè)計(jì)什么紅點(diǎn)系統(tǒng),什么彈窗系統(tǒng),其實(shí)大可以不必,UI框架做到上面那一層就可以了,至于具體的彈出式對話框怎么做,如何做,基于上面的機(jī)制來實(shí)現(xiàn)對應(yīng)的策略就可以了,所以我們做UI框架不做這些策略,具體的什么紅點(diǎn)提示這些,我們放到游戲邏輯層去做,當(dāng)作普通的開發(fā)需求就可以了。不要把系統(tǒng)彈窗和紅點(diǎn)這種設(shè)計(jì)到框架代碼中。
?
講完基本的機(jī)制以后,我們來看下具體如何實(shí)現(xiàn)的,任何一個(gè)GUI的視圖上面不會(huì)掛一個(gè)與邏輯相關(guān)的代碼組件,只會(huì)掛UI操作組件,如Sprite, Button等(也可以自己實(shí)現(xiàn)的,比如搖桿)。所以我們搭建代碼界面的時(shí)候,就是純界面的拖拉,加了按鈕,不掛響應(yīng)函數(shù)等。做好視圖以后,視圖放特定的位置,接下來就是顯示UI視圖,由UI框架提供接口,傳入視圖Prefab的路徑,就能把視圖顯示在Canvas場景中,生成UI視圖節(jié)點(diǎn)放場景后,再把對應(yīng)的代碼掛到UI視圖的根節(jié)點(diǎn)上。這里做一個(gè)約定,為了方便代碼維護(hù),UI視圖的名字對應(yīng)的UI視圖的控制代碼,是在UI視圖的名字后面加一個(gè)_Ctrl。這樣我們要查找一個(gè)UI視圖的控制代碼,只要賦值一下UI視圖的名字,找到帶_Ctrl的代碼就可以了。如圖1.6-1,UI視圖預(yù)制體與對應(yīng)的UI代碼的對應(yīng)關(guān)系,這樣維護(hù)起來就非常方便。代碼可以使用編輯器擴(kuò)展,在制作完成與之體后自動(dòng)生成對應(yīng)的模板。

同時(shí)所有的UI控制代碼我們放一個(gè)文件夾下,

接下來看下UIMgr中的的實(shí)例化UI界面的接口代碼,如圖

(1)實(shí)例化一個(gè)UI視圖節(jié)點(diǎn),到對應(yīng)的UI場景中;
(2)掛控制腳本到UI視圖的根節(jié)點(diǎn),并返回UI視圖節(jié)點(diǎn);
接下來我們來看下UI框架如何實(shí)現(xiàn)原則(2)(3),方便操作界面視圖與監(jiān)聽視圖事件。解決方案如下:
編寫一個(gè)UICtrl的基類,它繼承自Component組件類,然后在基類中實(shí)現(xiàn)方法,往UI控件上面添加事件響應(yīng)函數(shù)如圖

這樣監(jiān)聽UI的操作事件就變得很輕松了,只要傳入監(jiān)聽事件得節(jié)點(diǎn)在視圖中得路徑層次,就可以完成事件的監(jiān)聽。
如何方便的把UI的結(jié)果顯示到對應(yīng)的組件上,這個(gè)就更簡單了,因?yàn)槲覀冿@示UI結(jié)果的幾個(gè)組件我們可以在初始化的時(shí)候,寫好對應(yīng)的成員,初始化的時(shí)候,把組件獲取到,后面只要顯示數(shù)據(jù)到這個(gè)組件,直接操作就可以了。

這樣后續(xù)要更新UI的結(jié)果的時(shí)候,直接把結(jié)果更新到這些組件上即可。
?
具體代碼可以閱讀UIMgr.ts與UICtrl.ts,把實(shí)現(xiàn)原理自己再掌握一遍。