Unity UI架構(gòu)設(shè)計理念

Unity UI架構(gòu)設(shè)計理念

1.以ARPG為例,多個場景會反復(fù)出現(xiàn)相同的“UI窗體”,造成多個場景中反復(fù)加載相同的UI窗體。

解決方案:

????????????????“UI框架” 需要緩存項目(例游戲項目)中常用的“UI窗體"。


2.開發(fā)商業(yè)復(fù)雜項目時,各個UI(UI腳本)之間傳值,容易出現(xiàn)“緊耦合”(相互交錯,你中有我,我中有你)的情況。

解決方案:

????????????????各個UI的生成、銷毀、切換,都是通過框架(Manger)實現(xiàn),各個UI之間不直接聯(lián)系(傳值)。


3.卡牌、RPG等游戲類型項目,很多情況下會出現(xiàn)“UI窗體” 疊加現(xiàn)象。開發(fā)人員需要“手工”維護窗體中間的層級關(guān)系。

解決方案:
????????????????設(shè)計UI框架系統(tǒng),使用“棧”的數(shù)據(jù)結(jié)構(gòu),保存與控制當(dāng)前所有需要顯示的“UI窗體”的層級關(guān)系。


4.商業(yè)開發(fā)項目中的多個“UI窗體” 之間疊加出現(xiàn)時,必須保持“模態(tài)窗口”類型,否則容易出現(xiàn)誤操作。

解決方案??

設(shè)計的框架本身,需要對當(dāng)前顯示的窗體做“遮擋處理”,即:不允許用戶繞過當(dāng)前

“UI窗體”直接操作底層窗體,或者誤操作點擊項目中的3D游戲?qū)ο蟮?/p>


5.從以上問題還可以推導(dǎo)出如下“UI框架”需要注意的設(shè)計問題:

????????UI框架,需要管理加載“窗體預(yù)設(shè)”,進行自動加載的管理

????????UI框架,需要支持不同的語言環(huán)境,即語言的國際化。

? ????? 最后設(shè)計UI框架一個總的核心原則是:????

????????盡量讓框架本身完成與具體業(yè)務(wù)無關(guān)的事務(wù)性工作,讓開發(fā)人員只需要專注游戲業(yè)務(wù)邏輯的開發(fā)即可。(這個原則同樣適用于其他框架的設(shè)計中)



首先開發(fā)最簡版本功能設(shè)計:

??1:窗體自動加載管理。

??2:緩存UI窗體。

??3:窗體生命周期管理。

UI框架的核心類設(shè)計

??1: BaseUIForms 基礎(chǔ)UI窗體(父類)

??2: UIManger.cs UI窗體管理器

??3: UIType 窗體類型

??4: SysDefine 系統(tǒng)定義類

在Unity5.5安裝目錄下,建立腳本模版。

建立必要的目錄結(jié)構(gòu)與核心類,導(dǎo)入素材。

?BaseUIForms.cs

?UIManager.cs

?UIType.cs

?SysDefine.cs?[Config目錄下]

導(dǎo)入UI貼圖素材。

導(dǎo)入一些簡單的UI素材即可。


建立框架中的三個重要枚舉類型,定義 UIType 類。

??????UIFormsType?? UI窗體(位置)類型

??????UIFormsShowMode? UI窗體顯示類型

??????UIFormsLucencyType? 窗體透明度類型

?[提示: SysDefine 中定義]


定義“基礎(chǔ)UI窗體” BaseUIForms

定義 “UI管理器”? UIManager

? ? ? ?1: 定義“窗體路徑”與“窗體預(yù)設(shè)”的集合字段。

? ? ? ?2:定義“窗體預(yù)設(shè)”與管理腳本加載用的節(jié)點對象。

???????普通節(jié)點、固定節(jié)點、彈出節(jié)點、管理腳本節(jié)點。

? ? ? ?3:Unity編輯器中,定義“Canvas 根窗體”預(yù)設(shè)。

???????????????1>在測試場景中建立UI Panel 。

???????????????2>共建立3個Panel,與一個掛載腳本的空對象。

???????????????3>建立UI攝像機,設(shè)置參數(shù)。

???????????????4> Game視圖定義800*600 分辨率。

???????????????5>針對Canvas UI對象,設(shè)置合理參數(shù)


定義 “UI管理器”? UIManager (續(xù))

?4:定義“登陸窗體”、“選擇角色窗體”、“主窗體”等。

??????????1>建立各個窗體的Panel (注意:必須在Canvas 內(nèi)部建立)

??????????2>給各個窗體添加背景貼圖與必要按鈕等。

??????????3>定義的窗體都作為“預(yù)設(shè)”

定義 “UI管理器”? UIManager (續(xù))

?5:繼續(xù)開發(fā)UIManger 腳本,實現(xiàn)窗體的加載功能,且測試。

??????????1>主場景中,確保拖拽到層級視圖中的Canvas預(yù)設(shè)正確顯示。

??????????2>編寫Awake 事件函數(shù),對于常量都統(tǒng)一定義在SysDefine中。

??????????3>編寫“顯示UI窗體”公共方法。

??????????4>框架外建立測試腳本,測試UI窗體的基本加載功能。

?????????????1]建立框架外啟動加載腳本。

?????????????2]針對每個“窗體預(yù)設(shè)”都需要建立對應(yīng)的窗體腳本(繼承BaseUIForms)

?[備注:如果出現(xiàn)“baseUIForms==null, 請先確認(rèn)克隆對象上是否加載了BaseUIForms的子類”,說明“窗體預(yù)設(shè)”上必須添加BaseUIForms 的子類]

}定義 “UI管理器”? UIManager (續(xù))

?5:繼續(xù)開發(fā)UIManger 腳本,實現(xiàn)窗體的加載功能,且測試。(續(xù))

??5>? 測試以上所有步驟,成功如下圖所屬。

窗體層級管理

什么是“棧”數(shù)據(jù)結(jié)構(gòu)?

??是一種“先進后出”的數(shù)據(jù)結(jié)構(gòu),是一種常用算法。

??生活中的“漢諾塔”游戲、“摞燒餅”、“盤子堆”都是一種典型的“棧”結(jié)構(gòu)。


C#語言中提供 Stack泛型集合,來直接實現(xiàn)這種結(jié)構(gòu)。

常用屬性與方法:

Count 屬性?查詢棧內(nèi)元素數(shù)量

Push()?????壓棧

Pop()??????出棧

Peek()?????查詢棧頂元素

nGetEnumerator() 遍歷棧中所有元素

??演示:典型Demo示例。

開發(fā)“UI管理器”的“棧”數(shù)據(jù)結(jié)構(gòu),維護窗體的層級結(jié)構(gòu)。

定義Stack 類型字段。

顯示UI窗體 ShowUIForms() 方法中

????????1>“反向切換”屬性的窗體,定義“壓棧”方法

關(guān)閉(或返回上一個UI)窗體方法中

????????1>“普通”顯示屬性的窗體,定義關(guān)閉方法。

????????2>對于“反向切換”屬性的窗體,定義返回上一個窗體的方法(即:關(guān)閉)。

顯示UI窗體 ShowUIForms() 方法中

???????? 1>“反向切換”屬性窗體,定義“壓棧”方法

???????? 2> “隱藏其他”屬性窗體,定義顯示業(yè)務(wù)邏輯方法

關(guān)閉(或返回上一個UI)窗體方法中

???? ????1>“普通”顯示屬性的窗體,定義關(guān)閉方法。

???????? 2>對于“反向切換”屬性的窗體,定義返回上一個窗體的方法。 (即:關(guān)閉)。

????????3>“隱藏其他”屬性窗體,定義關(guān)閉邏輯方法

在多個UI業(yè)務(wù)窗體中,有時候需要客戶端程序主動清空“棧集合”中的當(dāng)前數(shù)據(jù),防止業(yè)務(wù)邏輯混亂。

?例如: RPG中的“商場系統(tǒng)”、“背包系統(tǒng)”、“任務(wù)系統(tǒng)”等。


具體代碼實現(xiàn):

??1:在UIType 類中,定義是否需要“清空反向切換”的字段(或者屬性)。

?2: 在UI管理器腳本中,關(guān)于顯示UI窗體的方法中,加入判斷清空棧中數(shù)據(jù)的業(yè)務(wù)邏輯即可。

定義如下窗體編寫代碼測試UI框架功能:

?登陸窗體:

????????注意事項: 所有窗體腳本都要繼承BaseUIForms

????????定義本窗體的類型(位置、顯示、透明度三大屬性),不寫則采用默認(rèn)數(shù)值。

? ? `? ? 注冊窗體按鈕事件。

?選擇英雄窗體:

?主城窗體:

?商城窗體:

?商品信息窗體:???

?程序重構(gòu)發(fā)現(xiàn),在UI框架內(nèi)部與客戶調(diào)用程序中都存在一些反復(fù)被使用的技術(shù)。

????????對于層級視圖的節(jié)點查找。

?????????(擴展方法)

????????獲取子節(jié)點(物體)的腳本

????????給子節(jié)點(物體)添加腳本

????????給子節(jié)點(物體)添加父對象


?程序重構(gòu)發(fā)現(xiàn),在客戶程序(UI框架)調(diào)用中,會反復(fù)出現(xiàn)一些常用的定義方式,例如:

????????按鈕的事件監(jiān)聽與注冊方法????

????????打開指定窗體

????????關(guān)閉指定窗體

????????發(fā)送消息

????????顯示語言信息


模態(tài)窗體管理

UI窗體中,很多彈出窗體要求玩家不能點擊“父窗體”,這就是“模態(tài)窗體”。

這里我們設(shè)計了四種模式類型:

? ? ? ? 完全透明、半透明、低透明度、透明且可以穿透。


在Canvas根窗體預(yù)設(shè)中(PopUp節(jié)點下)定義“UI遮擋面板”(_UIMaskPanel)窗體。

“UI遮擋面板” 就是一個普通的Panel。


平時這個面板是“不可見”狀態(tài)。

當(dāng)需要進行“模態(tài)”顯示的時候,則定義腳本,控制其在PopUp節(jié)點下倒數(shù)第二的位置,起到遮擋作用。

定義一個專門的控制腳本:“UIMaskMgr.cs”,以及在“窗體基類”(BaseUIForms.cs) 中控制“遮擋面板”的顯示與隱藏。


框架配置管理

所謂“配置管理”是指一個游戲項目(軟件項目),很多需要經(jīng)常變化的需求或者數(shù)據(jù),最好以配置文件的形式存在,從而代替“硬編碼”方式。

? 例如: 游戲項目語言的國際化、

???????? 日志文件的保存路徑等。


目前(2017)國際國內(nèi)普遍采用的配置管理方式主要有兩種: XML與Json 方式。

??兩者各有優(yōu)缺點:

? ? ? ? ? ?XML:對于數(shù)據(jù)的精確表示、易讀性很高。

?????????? 微軟很多的項目都內(nèi)置對XML作為配置文件的支持。

?????????(例如:網(wǎng)站項目:ASP.Net、 WinForm 等)

?????????? 缺點是讀寫速度慢,這個問題在移動端尤其突出。

??Json: 讀寫速度快,但是易讀性沒有XML好,但是可以接受。

?????????? 所以本框架項目都采用Json作為配置文件。

JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式。 JSON采用完全獨立于語言的文本格式,但是也使用了類似于C語言家族的習(xí)慣(包括C、C++、C#、Java、JavaScript、Perl、Python等)。這些特性使JSON成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成(一般用于提升網(wǎng)絡(luò)傳輸速率)。

JSON 語法 (JSON 語法是 JavaScript 對象表示語法的子集)

特點:

?數(shù)據(jù)在鍵值對中,數(shù)據(jù)由逗號分隔。

?花括號保存對象,方括號保存數(shù)組。

JSON 數(shù)據(jù)的書寫格式是:名稱/值對。 "firstName":"John"


開發(fā)Json配置管理器

定義通用配置管理器接口

開發(fā)實現(xiàn)IConfigManager 接口的通用配置管理器


UI管理器中關(guān)于“UI窗體預(yù)設(shè)路徑”集合中,把前面“硬編碼”改為應(yīng)用Json 配置管理的方式。

?????第1步在Resources 目錄下建立關(guān)于“UIFormsConfigInfo”的Json 文件。

?????第2步對于UIManager.cs 中的“UI窗體預(yù)設(shè)路徑”集合做配置管理。


日志調(diào)試

日志調(diào)試在游戲的開發(fā)全過程中占有非常重要的作用。

自定義“日志調(diào)試”腳本插件的開發(fā)思路與具體實現(xiàn)。

??現(xiàn)在為了更好的適用于PC與移動端調(diào)試的目的,進行再次重構(gòu)。

??第1:對于讀寫文件內(nèi)部方法做重構(gòu)完善,使得日志文件實現(xiàn)自動偵測與創(chuàng)建寫入操作等。

??第2: 改以前的針對XML的配置文件的讀取方式為Json 文件的讀取。

??目的一:提高讀取速度。

? ? ? ? ?二: 更好的應(yīng)用在移動端的部署

消息傳遞中心

基于Unity技術(shù)的游戲與項目研發(fā),目前提供的消息傳遞方式種類少,且耦合性很高。

?1:腳本組件公共方法、字段的相互調(diào)用。

????????例如: GetComponnet().TestMethod();

?2:SendMesage 技術(shù)。

?3:單例模式數(shù)據(jù)傳遞。

開發(fā)一種低耦合,無需考慮被傳遞對象(腳本名稱、組件名稱)的技術(shù)非常有價值。

“消息傳遞中心”:

??基于觀察者模式,利用委托與事件的基本機制原理,進一步封裝重構(gòu)的技術(shù)實現(xiàn)。

定義MessageCenter

?基本原理:



窗體基類(BaseUIForms) 中對于“消息傳遞中心”類常用方法的封裝。

?????發(fā)送消息 SendMessage()

?????接收消息 ReceiveMessage()

客戶程序消息傳遞多組數(shù)據(jù)的演示。

客戶程序建立“系統(tǒng)常量”類,方便程序復(fù)用與集中化管理


資源國際化

“資源國際化”對于游戲項目開發(fā)是指:語言、語音、貼圖、模型等國際化問題。

對于游戲項目,最常見的是針對不同國家的多語言版本的開發(fā),也就是“語言的國際化”。??

多語言版本的實現(xiàn),最基本的原理就是根據(jù)ID去讀取語言配置表,不同的語言新建一個語言配置表。


定義“語言管理器”(LanguageMgr)

基本原理:

??????1: 使用配置管理器腳本(繼承 IConfigManager接口),讀取不同語言的Json配置文件。

? ? ? 2: 使用 Dictionary 集合緩存“語言鍵值對”。

????? 3:定義顯示方法,根據(jù)ID查詢出對應(yīng)的語言信息


UI窗體基類(BaseUIForms) 對顯示語言的重構(gòu)。

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

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,661評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,785評論 18 139
  • 初白家搬了新家,住到了村北,這里離村子中心還有二里多路,還鮮有人家。今天村里有不少親戚都要去幫忙,所以大家要先到村...
    老鐵的五月麥田閱讀 213評論 0 1
  • 為什么喜歡繪畫?這么久了,終于,我算是找到了令自己都感到滿意的答案了。 鹿兒老師說,雖然水彩的技法上還有不少欠缺,...
    小曲奇兒閱讀 365評論 0 1
  • 有這樣一種現(xiàn)象,買房子是為了討媳婦,好像買了房子一定會找到一個自己喜歡的姑娘結(jié)婚,讀大學(xué),是為了找一份好工作,好像...
    綠芽茁壯閱讀 1,277評論 6 3