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

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

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

解決方案:

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


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

解決方案:

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


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

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


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

解決方案??

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

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


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

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

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

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

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



首先開發(fā)最簡(jiǎn)版本功能設(shè)計(jì):

??1:窗體自動(dòng)加載管理。

??2:緩存UI窗體。

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

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

??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)入U(xiǎn)I貼圖素材。

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


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

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

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

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

?[提示: SysDefine 中定義]


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

定義 “UI管理器”? UIManager

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

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

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

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

???????????????1>在測(cè)試場(chǎng)景中建立UI Panel 。

???????????????2>共建立3個(gè)Panel,與一個(gè)掛載腳本的空對(duì)象。

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

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

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


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

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

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

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

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

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

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

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

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

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

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

?????????????1]建立框架外啟動(dòng)加載腳本。

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

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

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

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

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

窗體層級(jí)管理

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

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

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


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

常用屬性與方法:

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

Push()?????壓棧

Pop()??????出棧

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

nGetEnumerator() 遍歷棧中所有元素

??演示:典型Demo示例。

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

定義Stack 類型字段。

顯示UI窗體 ShowUIForms() 方法中

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

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

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

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

顯示UI窗體 ShowUIForms() 方法中

???????? 1>“反向切換”屬性窗體,定義“壓?!狈椒?/p>

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

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

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

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

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

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

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


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

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

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

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

?登陸窗體:

????????注意事項(xiàng): 所有窗體腳本都要繼承BaseUIForms

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

? ? `? ? 注冊(cè)窗體按鈕事件。

?選擇英雄窗體:

?主城窗體:

?商城窗體:

?商品信息窗體:???

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

????????對(duì)于層級(jí)視圖的節(jié)點(diǎn)查找。

?????????(擴(kuò)展方法)

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

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

????????給子節(jié)點(diǎn)(物體)添加父對(duì)象


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

????????按鈕的事件監(jiān)聽(tīng)與注冊(cè)方法????

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

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

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

????????顯示語(yǔ)言信息


模態(tài)窗體管理

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

這里我們?cè)O(shè)計(jì)了四種模式類型:

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


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

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


平時(shí)這個(gè)面板是“不可見(jiàn)”狀態(tài)。

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

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


框架配置管理

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

? 例如: 游戲項(xiàng)目語(yǔ)言的國(guó)際化、

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


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

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

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

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

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

?????????? 缺點(diǎn)是讀寫速度慢,這個(gè)問(wèn)題在移動(dòng)端尤其突出。

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

?????????? 所以本框架項(xiàng)目都采用Json作為配置文件。

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

JSON 語(yǔ)法 (JSON 語(yǔ)法是 JavaScript 對(duì)象表示語(yǔ)法的子集)

特點(diǎn):

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

?花括號(hào)保存對(duì)象,方括號(hào)保存數(shù)組。

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


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

定義通用配置管理器接口

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


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

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

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


日志調(diào)試

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

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

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

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

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

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

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

消息傳遞中心

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

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

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

?2:SendMesage 技術(shù)。

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

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

“消息傳遞中心”:

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

定義MessageCenter

?基本原理:



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

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

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

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

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


資源國(guó)際化

“資源國(guó)際化”對(duì)于游戲項(xiàng)目開發(fā)是指:語(yǔ)言、語(yǔ)音、貼圖、模型等國(guó)際化問(wèn)題。

對(duì)于游戲項(xiàng)目,最常見(jiàn)的是針對(duì)不同國(guó)家的多語(yǔ)言版本的開發(fā),也就是“語(yǔ)言的國(guó)際化”。??

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


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

基本原理:

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

? ? ? 2: 使用 Dictionary 集合緩存“語(yǔ)言鍵值對(duì)”。

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


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

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

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

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

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