桑琪,葉德建
基于Unity3D游戲客戶端開發框架的設計與應用
桑琪,葉德建
游戲行業競爭日益激烈,從現有的游戲開發中汲取經驗形成框架是應對殘酷市場的必由之路。從實踐出發,從長期的游戲開發經驗中總結了一套通用的Unity3D游戲客戶端開發框架,采用通用管理器的方式有效組織管理場景中的游戲對象以及控制游戲對象的腳本,以通用組件的形式支持整個游戲功能系統的開發。簡述了UI框架、消息管理器、游戲對象緩存池3個框架層基礎組件的設計與實現,并以一款即時戰略游戲為例講解了如何利用該框架進行客戶端開發。
Unity3D;游戲客戶端框架;通用管理器
章編號:1007-757X(2016)06-0066-04
游戲作為近年來國家大力支持的文化創意產業,一直呈高速發展的趨勢。就《2015年中國游戲產業報告》顯示,中國游戲市場2015年收入達1407億,同比增長22.9%[1]。隨著游戲行業膨脹式的發展,中國游戲行業競爭越來越激烈。在這樣的市場環境下,如何利用更短的時間開發出高質量的游戲成為游戲開發人員關注的焦點。伴隨著游戲開發技術的成熟,游戲引擎不斷進化發展,極大提高了游戲開發的效率,Unity3D作為游戲引擎中的翹楚成為各大游戲尤其是3D游戲開發商們的首選。
Unity3D擁有著多個子系統,如渲染引擎、物理引擎、動畫系統、粒子特效等等,它們以組件的形式支持著游戲開發人員們的開發工作[2]。使用Unity3D開發游戲的基本原理是通過編寫腳本調用這些組件,生成并控制場景中的各類游戲對象從而形成一個完整的游戲。然而如何更加有效地組織管理場景中的游戲對象以及控制游戲對象的腳本,需要在游戲開發中有一定的技術及經驗積累。
Kim, Ae Hyun 、De Macedo等人針對應用Unity3D引擎進行游戲開發中的常用技術以及開發流程做了簡單介紹[3-6],于Unity3D引擎的理解僅僅停留于使用層面。王超明、呂林軒、郭一晶等都曾經介紹過某Unity3D游戲具體功能系統的設計與實現[7-9],但并沒有提取出通用的游戲客戶端開發框架。本文在實踐的基礎上,總結出一套通用的Unity3D游戲客戶端開發框架,將游戲開發中最常用的組件、功能整合起來,利用軟件復用的思想進一步提升了游戲開發的效率,同時還可形成技術上的沉淀。
Unity3D功能異常強大,它提供了各種API讓游戲開發者通過給游戲對象添加組件以及編寫腳本的方式實現各種游戲功能,如角色動畫、碰撞檢測、播放音樂音效等等。但如果整個游戲開發僅僅以疊加腳本添加組件的方式完成,不但無法實現復雜的游戲邏輯甚至還會讓整個項目混亂不堪難以維護[10]。因此我們要學會以通用管理器的方式統一組織管理同類的功能系統。以管理音效播放的管理器AudioManager為例,在Unity3D中,播放音樂音效需要在游戲場景的聲源處添加AudioSource組件用以掛載音頻源文件,在實際的游戲中我們往往需要在不同的時間播放不同的音效,因此需要實現一個AudioManager來管理游戲中的所有音樂音效的播放而非頻繁得掛載音頻文件。首先在AudioManager中維護一個音效字典,以key為標記,在管理器初始化時統一掛載好所有所需的音頻文件,當需要播放音頻的時候調用AudioManager對應的函數同時傳入所需音頻的key即可。
在整個游戲開發中,通用管理器的思想貫穿了從基本游戲框架到客戶端功能系統的設計實現,這種思想也與面向對象編程的思想相統一。整個游戲通常以組件式進行開發,一個組件往往是一個大的管理器,其中可能包含許多小的管理器。
同其他軟件開發一樣,游戲開發也遵循類似MVC框架的模型視圖分離的準則。沿用Unity3d本身的層級思想,本文的游戲框架也采用分層設計。整個游戲從下到上依次為系統層、框架層、數據層、控制層、視圖層,如圖1所示:

圖1 游戲分層設計示意圖
系統層,即游戲最終運行在什么平臺上。眾所周知,Unity3D可進行跨平臺發布,可發布游戲至IOS、Android、Windows phone 8等多種平臺。
框架層,顧名思義,游戲開發的通用底層支持,可輕松復用于不同游戲的開發,包括UI框架、消息管理器、游戲對象緩存池等基礎組件。
上面3層為大家所熟悉的MVC框架,即模型(model)-視圖(view)-控制器(controller)。
模型(Model)層用于處理游戲數據邏輯,負責在數據庫中存取數據或序列化與反序列化本地數據。我們將游戲數據劃分為兩大類:持久化數據和運行時數據。持久化數據包括游戲本身的配置表和用戶持久化信息,運行時數據是游戲運行時的臨時數據。
視圖(View)層包括UI層和各類游戲對象的行為表現。UI層即用戶看到的游戲界面,用以顯示相應的游戲數據。
控制(Controller)層是游戲開發中各類管理器的合集,從View層讀取數據,控制用戶輸入,并向Model層發送數據。集中表現在游戲對象的生成與控制。
采用此種劃分層次可以讓數據與邏輯分離,使游戲開發更具條理和效率。下文中我們先依次介紹框架層三個重要基礎組件的設計與實現,然后以ARPG游戲的游戲角色為例詳細解釋游戲對象的生成與控制。
游戲框架對于后期游戲功能系統的開發影響深遠,合理的游戲框架應該在提高游戲開發效率的前提下同時兼顧游戲項目的穩定性以及可擴展性,組件式的開發成為各游戲開發項目的首選。在這一部分,我們將介紹框架層三個非常重要基礎組件:基于NGUI的UI框架、消息管理器、游戲對象緩存池。
3.1基于NGUI的UI框架
NGUI是目前Unity3D游戲開發團隊最常用的UI插件,提供了強大的UI系統和事件通知框架。NGUI基于組件化、模塊化的原則,可以使開發者們使用非常少的代碼以及操作便可實現各類UI控件。
我們基于NGUI插件設計實現了一個UI框架,它具備以下功能特點:由UIManager統一管理游戲各UI界面的顯示、關閉、隱藏;提供插入界面動畫的接口;通過3個按鈕與相應回調函數的隱藏與顯示實現通用對話框;同時管理各UI界面的上下文Context,Context保存著UI界面的數據信息,我們通過棧的方式管理Context,從而實現界面的有序跳轉;用Mask遮罩提供插入新手教程的功能。應用此框架可以讓開發人員專注實現單個UI界面的邏輯而不用擔心界面的顯示關閉以及跳轉的實現,極大提高了游戲界面的開發效率。
3.2消息管理器
游戲通常要涉及各類游戲對象間的交互以及各個模塊的交互,為了實現模塊間的松耦合,我們一般采用消息驅動的方法來達到交互的目的。我們借鑒觀察者模式開發消息管理器模塊。模塊主要包括消息中心MessageCenter,消息觀察者Observer,消息發送者MessageSender,消息Message4部分,四者的交互活動圖如圖2所示:

圖2 消息管理器活動圖
MessageCenter是整個消息管理器的消息中樞,起著一個消息中介的作用,它維護一個消息隊列,負責接收以及轉發游戲的所有消息。Observer把自己以及自己感興趣的消息對應得注冊到MessageCenter中的消息隊列中,相對的當Observer對消息不再感興趣時,也可以隨時向MessageCenter取消注冊。EventSender產生并發送相應的Message到MessageCenter,MessageCenter會遍歷自己的消息隊列,找到監聽該消息的Observers并把Message轉發給它們。
我們舉個例子來說明消息管理器的應用。在游戲戰斗過程中,如果主角死亡往往會結束戰斗并跳出結算界面,但戰斗流程控制與角色行為管理是兩個不相關的模塊,如果角色行為管理器直接調用戰斗流程控制器的結算接口會增加兩個模塊的耦合性,這個時候我們便可以借助消息管理器。我們封裝一個MainPlayer_Dead的Message加入MessageCenter的消息隊列中供戰斗流程控制器注冊監控,當主角死亡時由角色行為管理器發送該消息即可。
消息管理器的應用讓我們避免了模塊間或游戲對象間交互時的顯示調用,讓游戲模塊間保持低耦合,非常方便游戲開發后期功能的擴展。
3.3游戲對象緩存池
前文中提到游戲由大量不同種類的游戲對象組成,這些游戲對象在游戲運行過程中需要不停地創建、銷毀,如果頻繁調用Unity3D游戲對象實例化API (GameObject.Ins -tiante())與對象銷毀API(GameObject.Destroy() )會造成游戲頻繁卡頓同時會產生很多內存碎片。游戲對象緩存池很好地解決了這一問題,它在合理利用設備內存的同時還能保證游戲畫面的流暢。游戲場景開始加載的時候我們預先實例化一定數量的接下來要用到的游戲對象,將游戲對象置為非激活狀態放入緩存池,對象實例化的數量根據需求決定,例如金幣同屏最多30個,則可以在最開始時實例化30個金幣。如圖3所示:

圖3 對象池設計圖
當外部需要某種游戲對象時可直接從緩存池獲取,然后把游戲對象置為激活狀態,外部用完該游戲對象后返還給緩存池并置回為非激活狀態。當切換游戲場景或終止游戲的時候,我們會對緩存池進行一次性清理。采用此種方式管理游戲對象非常有效地管理了內存并避免了內存泄漏。
為了驗證該客戶端框架的可用性,我們采用此框架實現了一款動作類即時戰略游戲,游戲場景、人物為全3D設計,以戰斗中控制大招點放,聚焦各人物特色技能為亮點。我們把該游戲的開發分為兩塊,戰斗系統和除戰斗系統之外的系統(簡稱外圍系統)。外圍系統通常包括人物養成系統、副本系統、商城系統、郵件系統等等,由于篇幅的限制,本文將主要介紹體現游戲核心玩法的戰斗系統。
我們將戰斗場景中的游戲對象分為兩大部分:前方UI界面與后方的場景對象。UI界面是2D的,后方場景對象則為3D。后方的場景對象一般包括角色對象、地圖資源、武器對象以及各類特效等等,體現了游戲的核心玩法。作為游戲的重要一部分,大量游戲界面用來顯示玩家與游戲內各類信息。上文我們已經介紹了基于NGUI的UI框架用來生成與控制大量的UI界面,這里我們將針對后方場景游戲對象的生成與控制進行簡單的介紹,并以戰斗中角色對象的管理器為例進行詳細的說明。
4.1游戲對象的生成與控制
一方面在戰斗場景中每個動態的游戲對象都是一個單獨的線程,不斷根據用戶的操作或者事件的進行自我更新并改變自身的行為,復雜的游戲對象往往需要幾個組件來控制自身的行為,如場景中的人物角色,需要動畫播放組件、位置管理組件、行為狀態機以及碰撞處理器等等,每個組件獨立負責自己的功能邏輯,在需要通信的時候利用上文介紹的消息管理器,這些組件采用組合模式,構成整個人物角色的控制器。游戲對象的種類多種多樣,因此我們一般采用Factory模式生成對象,將游戲對象各個組件的創建與初始化工作統一封裝起來。這里對應上文游戲對象緩存池的應用,實例化對象采用抽象工廠模式,不同的游戲對象注冊不同的工廠方法到對象池,以key為標記,非常方便后期新對象的擴展。游戲對象緩存池初始化時,根據工廠字典用不同的構造方法生成各類游戲對象加入緩存池的緩存隊列中,供上層隨時獲取對象。
另一方面游戲戰斗中一般都有暫停、恢復功能,甚至有幾倍速播放的需求,因此要求我們實現一個對象控制中心來統一管理所有的動態游戲對象。所有的游戲對象都需要實現IUpdate接口的Update方法,在該方法中更新所有的相關組件。當加載戰斗場景時,所有的對象從緩存池中獲取后便加入對象控制中心的更新隊列中,戰斗進行時通過對象控制中心統一調用Update方法來定時更新所有游戲對象,這樣我們便可以通過控制Update方法的調用頻率來實現所有游戲對象統一暫停、恢復以及變速播放的目的。
4.2角色管理器
角色對象是游戲戰斗中最重要的組成元素,要想充分地吸引并留住玩家除了精致的角色美術模型還要有合理流暢的管理器,因此角色管理器的設計在游戲總體設計中處于核心地位。它需要的主要組件如圖4所示:

圖4 游戲角色管理組件圖
我們將依次介紹組件的設計與實現。
4.2.1動畫管理器
任何游戲都離不開動畫,尤其在突出人物角色的游戲中,角色動畫是否逼真、流暢直接關系到游戲的直接體驗。動畫的逼真程度往往取決于美術工作人員,但動畫是否能自然融合和過度以及跟周圍環境進行交互還是程序開發人員的工作。
Unity3本身提供了動畫播放組件Animation和Animator,它支持動畫播放、停止、改變速度以及動畫融合。但這些并不足以滿足我們復雜的系統需求,Unity3D本身的動畫播放組件是基于時間自動播放動畫的,但我們需要動畫組件服從對象控制中心的統一調用進行幀更新,于是我們編寫了動畫管理器組件,它實現了以下功能:提供一個適配層讓動畫根據幀來進行播放,從而實現動畫的暫停、恢復以及變速播放;加入伴隨角色動畫的特效動畫,讓特效動畫與角色動畫保持同步播放;同時加入動畫事件系統,實現動畫依賴的事件回調,如角色攻擊的傷害判定。
應用此動畫管理器組件可以方便得控制角色動作的播放,添加動畫事件與周圍環境進行流暢交互,增加角色運動的多樣性,給玩家帶來強烈的視覺感受。
4.2.2行為管理器
游戲角色在游戲運行時往往有著不同的行為狀態,如待機、攻擊、奔跑等等。游戲角色在不同的行為狀態下會產生不一樣的行為,并會在達到一定條件時切換行為狀態,這便構成了角色的行為狀態機。我們采用了狀態機模式實現了行為管理器,所有行為實現三個接口供行為管理器調用,分別為:狀態更新Update,進入狀態OnEnter,離開狀態OnExit。行為管理器作為角色行為狀態的控制中心,它維護該角色所有會產生行為的字典,以行為枚舉類為key,同時維護角色當前唯一的行為狀態currentBehavior,行為管理器每幀的更新操作會調用currentBehavior的更新操作,當達到一定條件時調用設置行為的函數并傳入枚舉類值來切換行為狀態,此時會自動調用老行為狀態的OnExit操作,同時調用新行為狀態的OnEnter操作。
采用行為管理器控制角色行為邏輯,可以讓開發者更加關注每個行為的具體邏輯而不用擔心狀態的切換。
4.2.3碰撞處理器
游戲尤其動作類游戲中避免不了對碰撞事件的處理,例如子彈碰到角色需要處理角色受擊,NPC角色在行走模式時碰到敵方角色或塔防需要切換至攻擊模式,碰到友方角色或塔防等障礙物需要改變行進路線。Unity3D提供了碰撞檢測的API,需要給游戲對象添加碰撞器Collider跟剛體Rigidbody組件。碰撞器有各種形狀,Box Collider、Sphere Collider、Mesh Collider等等,我們可以根據具體需求來進行選擇。剛體用來描繪游戲對象的各種物理屬性,可以讓游戲對象在碰撞后嚴格遵照物理規則來運動。兩個游戲對象產生碰撞的前提是,兩個對象都帶有碰撞體同時至少其中一個對象帶有剛體。
Unity3D內的碰撞處理的方式有兩種,一種是利用碰撞器,游戲對象碰撞前后會調用碰撞函數OnCollisionEnter/ Stay/Exit,同時根據物理規則產生碰撞效果。另一種是利用觸發器,即把對象身上碰撞器的IsTrigger屬性置為True,這種情況下僅調用碰撞函數OnTriggerEnter/Stay/Exit,而不產生任何碰撞效果。
游戲開發過程中,為了保證對所有游戲對象的可控性,我們一般采用后者來處理碰撞。我們的角色碰撞處理器便是為了處理游戲對象間的碰撞事件,它繼承于MonoBehavior腳本覆寫以下幾個函數:
MonoBehaviour.OnTriggerEnter(Collider other)當進入觸發器MonoBehaviour.OnTriggerExit(Collider other)當退出觸發器MonoBehaviour.OnTriggerStay(Collider other)當逗留觸發器我們可以通過傳入的Collider獲取相應的游戲對象從而處理一系列的碰撞事件。
我們應用上文描述的客戶端開發框架開發了一個全3D即時戰略游戲,該游戲項目實現了多種復雜的游戲系統,穩定并具有很強的擴展性。目前該項目已經上線運營,精細的畫風配合流暢多樣的玩法得到玩家的一致好評,如圖5所示:


圖5 游戲效果圖
圖5(a)為游戲的主界面,中間部分展示的人物角色可以通過碰撞與玩家進行交互,周圍的UI部分展示了游戲的個功能入口。圖5(b)為抽獎界面,得意于功能強大的UI框架,抽獎面板可來回翻轉。圖5(c)為炫酷的戰斗場景,玩家可通過點擊下方人物頭像釋放對應人物技能。
本文闡述了一套通用的Unity3D游戲客戶端開發框架,并利用此框架開發了一個全3D即時戰略游戲。實踐證明,好的Unity3D程序員不僅要熟練使用引擎本身,還要學會在開發過程中吸取經驗教訓,總結出好的游戲開發框架,將通用常用的功能組件提取整理,如此可以很大程度上減少開發下一個游戲的工作量。除此之外我們還要學會與團隊其他成員保持良好的溝通。
[1] 中國游戲產業報告[Z]. 2016.
[2] 謝文斌. 基于游戲引擎的沉浸式立體顯示游戲框架設計與實現[D]. 復旦大學, 2013.
[3] Kim A H, Bae J H. Development of Mobile Game Using Multiplatform (Unity3D) Game Engine[J]. International Journal of Intelligent Information Processing. 2014.
[4] De Macedo D V, Formico Rodrigues M A. Experiences with rapid mobile game development using unity engine[J]. Computers in Entertainment. 2011, 9(3): 1-12.
[5] Xie J. Research on key technologies base Unity3D game engine[C]. 2012.
[6] Jie J, Yang K, Haihui S. Research on the 3D Game Scene Optimization of Mobile Phone Based on the Unity 3D Engine[C]. 2011.
[7] 王超明. 基于 Unity3D 引擎的賽車手機游戲的設計與實現[D]. 北京交通大學, 2015.
[8] 呂林軒. 基于 Unity3D 的 “全民快跑” 客戶端的設計與實現[D]. 北京交通大學, 2015.
[9] 郭一晶, 吳文樹. 基于 Android 的飛行射擊游戲的設計與實現[J]. 微型電腦應用, 2014, 30(6): 13-15.
[10] 左強. 設計模式與游戲開發[J]. 程序員:游戲創造. 2006(3): 56-62.
Design and Application of Mobile Game Client Development Framework Based on Unity3D
Sang Qi1,2, Ye Dejian1,2
(1. Software School, Fudan University, Shanghai 201203, China;2. Engineering Research Center of Cyber Security Auditing and Monitoring, Ministry of Education, Shanghai 201203, China))
Along with the increasingly fierce competition in the game industry, forming a framework from the experience of existing game development is the only way to deal with the brutal market. This paper sums up a general framework for the development of the Unity3D game client based on the long-term game development experience, which uses the method of general manager to effectively organize the game objects in the scene as well as the control scripts of the game objects. In this paper, it first briefly describes three basic components in the frame layer including UI framework, message manager and buffer pool of game objects. Then it explains how to use the framework for client development with a real-time strategy game as an example.
Unity3D; Game Client Framework; General Manager
TP311
A
2016.02.20)
桑 琪(1990-),女,復旦大學,軟件學院,網路信息安全審計監控教育部工程科研中心,碩士,研究方向:網絡多媒體,上海,201203
葉德建(1976-),男,復旦大學,軟件學院,網路信息安全審計監控教育部工程科研中心,副教授,博士,研究方向:寬帶網絡與互動媒體,上海,201203