簡易 Unity3D UI 框架

看見一篇介紹 Unity3D UI 框架編寫的文章,并且給出了示例代碼。然后去了解了一下。講道理,示例代碼蠻亂的,不知道有一些是不是直接從項目代碼拷貝然后簡單修改,對于一個簡單的框架來說,有很多不必要的混亂邏輯。而且我又喜歡粉色,所以就重新編寫了,話不多說先上運(yùn)行圖示。具體代碼點這里

運(yùn)行圖示

想了解更多信息具體查看代碼。這篇博客主要談一談 UI 框架基本的需求。UI 框架有很多實現(xiàn)方式,比如多個界面共用一個攝像機(jī)渲染還是單個界面單個攝像機(jī)渲染,但是基本的需求是一致的。掌握了基本的需求,才能適應(yīng)不同項目策劃百變的需求。最后需求分析基于手游,界面基于 NGUI

基本情景

UIOper

游戲玩法一般分為 UI 玩法和核心玩法。假設(shè)核心玩法是戰(zhàn)斗。UI 玩法與核心相互交織連接,比如打開裝備界面鍛煉裝備,這樣戰(zhàn)斗時就更厲害,還比如打開聊天界面與好友聊天,一起組隊打 Boss 。上圖是常見的操作之一,總結(jié)為兩句話:界面之間跳轉(zhuǎn),界面與戰(zhàn)斗跳轉(zhuǎn),這是最基本的需求情景。

了解了基本情景后來探索更多的細(xì)節(jié)吧。

界面渲染

渲染是最現(xiàn)實的問題,畢竟界面要先能被看見。新創(chuàng)建一個 Camera 獨立負(fù)責(zé)界面渲染,和主場景和戰(zhàn)斗場景渲染獨立開來。對于這個只渲染 UI 的 Camera 設(shè)置 Camera.cullingMask 指定渲染的 Layer,避免冗余渲染,同樣界面(GameObject)的 Layer 也要設(shè)置為值才能被顯示 。這樣當(dāng)調(diào)節(jié)戰(zhàn)斗場景和主場景攝像機(jī)渲染時,UI 不會受到影響,相應(yīng)的修改 UI Camera 的選項時,也不會影響非 UI 的渲染。

界面跳轉(zhuǎn)與界面層級(depth,深度值)

界面跳轉(zhuǎn)與界面層級是相互關(guān)聯(lián)的。比如某個導(dǎo)航按鈕打開一個新的界面,但新的界面層級比較低,這樣在重疊區(qū)域?qū)Ш桨粹o就會遮擋新打開的界面,這不符合實際需求,因此需要合理的管理界面層級,防止出現(xiàn)錯誤的遮擋。界面跳轉(zhuǎn)涉及多個界面,界面層級涉及到渲染次序進(jìn)而影響顯示順序,NGUI 中可以用 depth 控制渲染次序,UGUI 又是另一種方式控制渲染次序,這里使用 NGUI 深度值進(jìn)行描述,目的都是一樣的,就是控制渲染秩序。

當(dāng)游戲界面足夠的簡單,UI 管理就更簡單。如下所示。比如僅僅創(chuàng)建兩個 UIPanel,ToolPanel 深度值更大,顯示優(yōu)先級更高,PlayPanel 優(yōu)先級低一些,用來展示玩法,由于游戲界面很簡單,此時完全可以把所有界面都創(chuàng)建好,如 UI1 和 UI2 。比如需要顯示 UI2 時,設(shè)置 UI1 為 Inactive 然后設(shè)置 UI2 為 Active 。通過這種方式,你就可以完成一個超簡單的 UI 框架,當(dāng)然它的功能備受限制,但是對于簡單的小游戲來說,也足夠了。

UIRoot
    PlayPanel
        UI1
        UI2
    ToolPanel
        Tool

然而很多時候游戲會涉及很多界面。這樣就得考慮更靈活的實現(xiàn)方式。

  • 縮放選擇。NGUI 使用 UIRoot 組件進(jìn)行縮放。因此完全可以所有界面共用一個 UIRoot 組件。如下格式。Panel1 到 Panel3 是三個不同的界面。
UIRoot
    Panel1
        Panel2
        Panel3

當(dāng)然若不在乎冗余的 UIRoot 組件,或者想個別界面采用特俗的縮放方式,也可以每個節(jié)目單獨一個 UIRoot 組件。如下。

UIRoot1
    Panel
UIRoot2
       Panel
UIRoot3
       Panel
  • 攝像機(jī)選擇。再提一下,攝像機(jī)指定 Layer 且 UI 界面 GameObject 的 Layer 設(shè)置為值。
  • 每個界面單獨一個攝像機(jī)。設(shè)置界面所在攝像機(jī)的 Camera.depth 即可設(shè)置界面層級。這種方式需要避免攝像機(jī)錯亂,例如界面 A 的攝像機(jī)又渲染了界面 B 。有一種解決方法是設(shè)置 UIRoot 的位置,避免不同界面出現(xiàn)重疊。
  • 所有界面共用單個攝像機(jī)。修改界面層級通過設(shè)置 UIPanel.depth 。這種方式設(shè)置界面層級時需要設(shè)置該界面所有 UIPanel.depth 。比如設(shè)置 depth 是 1000,則需要排序該界面所有 UIPanel 然后從小到大分別設(shè)置為 1000 、1001 、1002 等。
  • 界面類型。游戲中存在不同類型的界面,有些界面就應(yīng)該具有更高的優(yōu)先級,遮擋住其他界面,例如導(dǎo)航界面。還有一種常見的就是玩法的界面,不同的玩法界面相對獨立。比如當(dāng)界面 A 與界面 B 交互時,此時采用窗口跳轉(zhuǎn)即可。
  • 界面跳轉(zhuǎn)。打開新界面時,是否禁用其他渲染。關(guān)閉新界面時,恢復(fù)之前的渲染狀態(tài)
  • 禁用其他渲染(包括禁用主場景渲染)。打開全屏窗口時可以采用此方式。此時設(shè)置新界面層級,可以直接設(shè)置深度值。
  • 不禁用其他渲染。打開非全屏窗口時可以采用此方式。此時設(shè)置新界面層級,需要動態(tài)計算深度值(可以遞增深度值)并設(shè)置到界面,使新界面可以遮擋其他相應(yīng)界面顯示。
  • 界面深度值管理。NGUI 采用深度值。UGUI 是另外一種方式。總之目的是實現(xiàn)合理的界面遮擋。
  • 界面與戰(zhàn)斗。進(jìn)入戰(zhàn)斗后,一般之前的那些玩法界面都需要被隱藏,取而代之的是用于戰(zhàn)斗中的界面。退出戰(zhàn)斗后關(guān)閉戰(zhàn)斗中的界面,然后再恢復(fù)進(jìn)入戰(zhàn)斗前的玩法界面狀態(tài)。當(dāng)然了進(jìn)入戰(zhàn)斗后如果退出了未顯示場景,此時可以停止主場景的渲染。
  • 界面與消息屏蔽。比如界面 A 顯示在界面 B 的上方,一般情況下肯定都不想在界面 A 上隨便點擊,卻觸發(fā)了界面 B 上的事件,對吧。因此這一項也是需要考慮的。

這些都是基本的 UI 框架需求。這些需求可以根據(jù)項目情況或簡單或復(fù)雜實現(xiàn)。相信讀到這里,你內(nèi)心也有了一些自己的想法了,是吧。

再進(jìn)一步,資源,內(nèi)存,效率

  • 界面資源。實際項目中很多界面,不可能全部載入到內(nèi)存,因此都是用到時才加載。若所有界面被單一個攝像機(jī)渲染,資源文件就不用包含攝像機(jī),只需包含相應(yīng)的面板即可。
  • 資源可被保存到 .unity 文件。使用時加載 .unity 文件。
  • 資源也可被保存到 prefab 文件中。
  • 界面內(nèi)存。若界面不多,使用的界面就一直存放在內(nèi)存中。若需要考慮性能,則要處理資源銷毀從而騰出內(nèi)存空間。
  • 效率問題。若界面很大且包含了更多的內(nèi)容,打開界面時若全部加載所有內(nèi)容,會導(dǎo)致界面打開比較慢。此時就可以考慮界面拆分。先載入必須顯示的內(nèi)容,剩下的內(nèi)容根據(jù)需要動態(tài)加載。這一步可以單個界面自己負(fù)責(zé)實現(xiàn),也可以考慮到整合到框架中,方便使用的開發(fā)者。

開發(fā)

到這一步一個框架就開發(fā)出來使用了。在實際項目需求中可能會為了便利性,進(jìn)一步增加一些通用功能。下面列舉一些項目中會實際處理的事情。

  • 打開界面時,傳遞參數(shù)。
  • 打開和關(guān)閉界面時,播放動畫。
  • 界面的刷新,包括玩法上的主動刷新(如獲取新的道具刷新背包)或者斷線重連后的刷新。
  • 界面的重復(fù)打開。
  • 界面顯示特效。
  • 界面顯示模型。

下面是前面提到的我重新實現(xiàn)的小框架的例子。例子很簡單,就是顯示一個界面。在 Awake 中進(jìn)行初始化處理即可。之后便可以調(diào)用 WndMgr.inst.ShowWindow(WndId.shop); 來顯示界面。

using UnityEngine;
using TinyWnd;

public class ShopWnd : Wnd
{
    protected override void OnAwake()
    {
        _wndId = WndId.shop;
        _colliderMode = WndColliderMode.transparent;
        _closeClickBg = true;
        _unifiedClose = true;
    }
}

提一點,組件中 AwakeStart 執(zhí)行順序,大家都知道。要注意的地方是 AwakeStart 不一定是在同一幀執(zhí)行。當(dāng)調(diào)用 AddComponent 添加新的組件時,初始化完畢后 Awake 會被調(diào)用,而 Start 未被調(diào)用。因此組件的一些初始化處理放在 Awake 函數(shù)中會更加合適。這樣的話,動態(tài)添加這個組件后就可以使用了,而不用擔(dān)心一些初始化操作未被執(zhí)行。


我的博客地址 https://my.oschina.net/iirecord/blog

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內(nèi)容