當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 一瞥Unity集成開發(fā)環(huán)境中的軟件工程設(shè)計思想
概述: 本文對Unity集成開發(fā)環(huán)境主要部分進行了軟件工程技術(shù)上的拆解,嘗試從交互式的編程技術(shù)、正向與反向工程、設(shè)計模式、組件模型設(shè)計、 面向?qū)ο蟮脑O(shè)計和軟件可擴展性等幾個方面進行了論述,為想深入了解Unity開發(fā)世界的技術(shù)人員奠定基礎(chǔ)。
1 背景
Unity是一個強大的集成游戲引擎和編輯器,可以讓開發(fā)者可以迅速高效地創(chuàng)建對象、導(dǎo)入外部資源,并且用代碼把它們連接在一起。Unity編輯器是 可視化的,其圍繞這樣的原則而構(gòu)建,即開發(fā)者可以使用一個簡單的拖放動作來完成任何任務(wù),甚至可以連接腳本,自己編寫程序?qū)崿F(xiàn)特定的功能。
鑒于Unity 3D的集成開發(fā)環(huán)境的安裝和搭建已經(jīng)有了論述,我們試圖對Unity集成環(huán)境進行簡要的技術(shù)解析。下面會首先介紹Unity總體集成 開發(fā)環(huán)境的主界面布局,而后對Unity的軟件工具設(shè)計思想進行軟件技術(shù)上的分析。
2 總體開發(fā)環(huán)境概覽
正如Visual Studio為微軟公司的Windows平臺提供高效的開發(fā)環(huán)境一樣,Unity的集成開發(fā)環(huán)境為虛擬現(xiàn)實(AR/VR/MR)平臺的開發(fā)提供了有力的生產(chǎn) 力工具。下面對開發(fā)界面布局中涉及的主要子窗口略要說明。
• Scene【場景面板】:該面板為Unity3D的編輯面板;你可以將你所有的模型、燈光、 以及其他材質(zhì)對象拖放到該場景中。構(gòu)建游戲中所能呈現(xiàn)景象。
• Game【游戲面板】:與場景面板不同,該面板是用來渲染場景面板中景象的。該面 板不能用作編輯,但卻可以呈現(xiàn)完整的動畫效果。
• Hierarchy【層次清單欄】:該面板欄主要功能是顯示放在場景面板中所有的物體對 象。
• Project【項目文件欄】:該面板欄主要功能是顯示該項目文件中的所有資源列表。 除了模型、材質(zhì)、字體等,還包括該項目的各個場景文件。
• Inspector【監(jiān)視面板】:該面板欄會呈現(xiàn)出任何對象的所固有的屬性,包括三維坐 標(biāo)、旋轉(zhuǎn)量、縮放大小、腳本的變量和對象等等。
• 【場景調(diào)整工具】:可改變你在編輯過程中的場景視角、物體世界坐標(biāo)和本地坐標(biāo) 的更換、物體法線中心的位子,以及物體在場景中的坐標(biāo)位置,縮放大小等等。
• 【播放、暫停、逐幀按鈕】:用于運行游戲,暫停游戲和逐幀調(diào)試程序。
• 【層級顯示按鈕】:勾選或取消該下拉框中對應(yīng)層的名字,就能決定該層中所有物 體是否在場景面板中被顯示。
• 【版面布局按鈕】:調(diào)整該下拉框中的選項,即可改變編輯面板的布局。
• 【菜單欄】:和其他軟件一樣,包含了軟件幾乎所有要用到的工具下拉菜單。
圖 1 Unity中文集成開發(fā)環(huán)境
圖 2 Unity英文集成開發(fā)環(huán)境
由于中英文表達習(xí)慣的不同,不同的技術(shù)人員對術(shù)語的中文表達存在差異性,下面為了讀者更好地理解,特此總結(jié)表格如下:
3 交互式編程技術(shù)
3.1 引言
計算機科學(xué)領(lǐng)域,交互式編程技術(shù)很早就有了實現(xiàn)版本,比如Tcl/Tk語言應(yīng)用在美國很多高校的實驗室和研究所,用來快速展現(xiàn)原型設(shè)計。鑒于很多 工程師剛走出校門,很多從編譯型語言收益,尤其是c/c++,因此容易養(yǎng)成了“慣性”。隨著現(xiàn)代編程語言的大量涌現(xiàn),比如python語言,特別是網(wǎng)絡(luò) 經(jīng)濟所催生的“短-平-快”模式,使得交互式的編程語言技術(shù)更加契合技術(shù)人員的生活。比如:
Python語言
Python的設(shè)計哲學(xué)是“優(yōu)雅”、“明確”、“簡單”,是一門完全面向?qū)ο蟮恼Z言。IDLE是Python軟件包自帶的一個集成開發(fā)環(huán)境,初學(xué)者可以利用 它方便地創(chuàng)建、運行、測試和調(diào)試Python程序。IDLE帶有一個編輯器,用來編輯Python程序(或者腳本);有一個交互式解釋器用來解釋執(zhí)行Python 語句;有一個調(diào)試器來調(diào)試Python腳本。正式由于交互的解釋器為該編程語言提供了便利。
Ruby語言
Ruby是一門開源的動態(tài)編程語言,注重簡潔和效率。因此Ruby 的句法優(yōu)雅,讀起來自然,寫起來舒適。它也是一種簡單快捷的面向?qū)ο螅嫦驅(qū)ο蟪?序設(shè)計)腳本語言,它的靈感與特性來自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp 語言。Ruby的交互性可以通過“irb”展現(xiàn)。irb是一個交互式 的Ruby界面(Ruby解釋器)?梢酝ㄟ^irb來調(diào)試、運行和實驗Ruby代碼。這意味著它不用處理文件,可以直接在會話中輸入代碼,測試Ruby代碼,同 時也是一個學(xué)習(xí)Ruby的好工具。
Powershell/Bash
Bash是Unix系統(tǒng)或類Unix系統(tǒng)支持很久的shell解釋器,Powershell是微軟公司新型針對Windows平臺的解釋器,兩者都可以通過技術(shù)人員敲命令快速 實現(xiàn)編程。正是由于應(yīng)用的普遍性,使得很多技術(shù)人員忽略了它們本身就是一門很好的,有用的和便捷的交互式編程語言。但缺點就是跟其它圖形化 的解釋器相比,在可視化編程方便還仍顯得笨拙和低效。
總之,交互式的編程語言(很多是腳本語言)都提供類似的控制臺,直接輸入腳本語句,回車就執(zhí)行了,結(jié)果立即顯示出來,無須經(jīng)過復(fù)雜的保存和 編譯階段。
3.2 Unity集成環(huán)境的場景面板
Unity 3D中,“場景”是一個視圖,我們通過“場景”這個視圖,來編輯、布置游戲中玩家所能見到的圖像和聲音。場景包含游戲的對象。它們可以 用來創(chuàng)建主菜單、個人級別(level)和其他任何東西。認為每個獨特的場景文件作為一個獨特的級別(level)。在每一個場景中,你將放置你的環(huán) 境,障礙和裝飾,從而設(shè)計和構(gòu)建了你的游戲。
在開發(fā)過程中,我們能在“Scene”視圖中,就可以直接放入所有的游戲?qū)ο螅ㄎ矬w),從而共同形成一個場景,而且會在Hierarchy視圖中通過層級 關(guān)系列出來。
圖 1 當(dāng)前3個發(fā)展方向
透過上面的分析,我們能夠看到Unity環(huán)境很好滴沿用了現(xiàn)代編程語言的交互式開發(fā)模式和體驗,只需用戶將需要的物體放入場景(如圖中放入一個球 體),Hierarchy選項卡就可以實時看到物體的諸多屬性;反過來用戶修改某個屬性信息又可以在場景環(huán)境中實時地看到變化。而且,在游戲(Game) 選項卡中用戶能夠預(yù)覽到運行時的場景變化。
4 正向工程與反向工程
4.1 引言
反向工程也稱逆向工程(英文是reverse engineering),是相對正向工程而言,大意是根據(jù)已有的東西和結(jié)果,通過分析來推導(dǎo)出具體的實現(xiàn)方法。 在我們現(xiàn)實的軟件世界里,比如從某個能夠做出某種動畫效果的可執(zhí)行程序(.exe/elf),通過反匯編、反編譯和動態(tài)跟蹤等技術(shù)方法,分析出其動 畫效果的實現(xiàn)過程,這種行為就是逆向工程;不僅僅是反編譯,而且還要推倒出設(shè)計,并且文檔化,逆向軟件工程的目的是使軟件得以維護。再比如 Java代碼或C#代碼通過逆向構(gòu)建 UML 類及序列圖時,能夠使得技術(shù)人員改動代碼的同時實時更新建模圖形的變化。技術(shù)人員往往通過IBM® Rational® Software Architect 將 Java源代碼做逆向工程生成 UML 類和序列圖,通過.Net / Visio軟件工具將C#源代碼做逆向工程諸如此類。
4.2 Unity集成環(huán)境的屬性查看器
明白了上面提到的軟件工程思想后,讓我們瞧一瞧Unity是如何體現(xiàn)這一點的。
上面的圖說明的是: 用戶能夠通過操作Unity的環(huán)境菜單生成C#腳本文件;反之,用戶又可以通過修改腳本文件來改動Inspector面板的布局。比如, 正如圖中顯示的腳本文件中增加了Test類,在Inspector面板中有相應(yīng)的更新顯示。此外,如果用戶對缺省的面板風(fēng)格不滿意,用戶還能夠通過在腳本 文件中繼承Editor類的方法對監(jiān)視面板進行大幅度的改動。我們能夠看到,這里充分體現(xiàn)了反向工程的設(shè)計思路。
5 單實例設(shè)計模式
5.1 設(shè)計模式
按照設(shè)計模式總結(jié)的幾大類軟件模式設(shè)計角度,單例模式是一種對象創(chuàng)建模式,它用于產(chǎn)生一個對象的具體實例,它可以確保系統(tǒng)中一個類只產(chǎn)生一 個實例。比如說,Java 里面實現(xiàn)的單例是一個虛擬機的范圍,因為裝載類的功能是虛擬機的,所以一個虛擬機在通過自己的 ClassLoad 裝載實現(xiàn)單 例類的時候就會創(chuàng)建一個類的實例。在 Java 語言中,這樣的行為能帶來兩大好處:
1 對于頻繁使用的對象,可以省略創(chuàng)建對象所花費的時間,這對于那些重量級對象而言,是非?捎^的一筆系統(tǒng)開銷;
2 由于 new 操作的次數(shù)減少,因而對系統(tǒng)內(nèi)存的使用頻率也會降低,這將減輕 GC (指JVM的內(nèi)存回收算法)壓力,縮短 GC 停頓時間。
因此對于系統(tǒng)的關(guān)鍵組件和被頻繁使用的對象,使用單例模式可以有效地改善系統(tǒng)的性能。單例模式的核心在于通過一個接口返回唯一的對象實例。
5.2 Unity的單實例運用
在Unity的集成開發(fā)環(huán)境中,對IDE環(huán)境的配置可以通過偏好(Preferences)選項窗口進行全局性的配置,包括編輯器的選擇,顏色的選擇,快捷鍵的 設(shè)置等等,這些配置信息保存到配置文件中構(gòu)建了全局唯一的配置實例。
比如外部工具選擇的腳本編譯器選項,在Mac系統(tǒng)環(huán)境下,可以選擇MonoDevelop或者Xamarin Studio兩種開發(fā)工具,相應(yīng)地Windows系統(tǒng)環(huán)境下,可以 選擇MonoDevelop或者Visual Studio兩種IDE開發(fā)環(huán)境。這種設(shè)計思路往往在很多的可視化工具設(shè)計環(huán)境當(dāng)中,我們能夠找到很好的例子。另外,這里 展現(xiàn)的Unity環(huán)境一個不同于其它環(huán)境的特點就是考慮了設(shè)計工具的協(xié)同工作,直接和其它現(xiàn)成的優(yōu)秀開發(fā)工具一道為項目開發(fā)更好地服務(wù)。
6 組件化設(shè)計
6.1 模塊化設(shè)計
早在C語言大行其道的時代,基于模塊化的設(shè)計思想受到了很大的歡迎。通過接口和實現(xiàn)分離的形式,在項目開發(fā)實踐中得到了廣泛的運用。微軟公司 倡導(dǎo)的基于構(gòu)件(Component)或組件的開發(fā)模式,構(gòu)建了微軟操作系統(tǒng)的設(shè)計哲學(xué),尤其是.Net生態(tài)系統(tǒng),從早期低效的ActiveX控件到com, 到現(xiàn)在 的com+,直到.Net的成熟,微軟公司把組件對象模型技術(shù)發(fā)揮的淋漓盡致。
但好多技術(shù)人員還是把模塊化和組件化混為一談,兩者有著共性和個性。兩者理解上是否存在差異往往取決專業(yè)背景、所在領(lǐng)域、以及視角。 從設(shè)計上來看,組件強調(diào)復(fù)用,模塊強調(diào)職責(zé)(內(nèi)聚、分離),或者說組件是達到可復(fù)用要求的模塊。模塊或模組(Module)的核心意義是分離職責(zé), 屬于代碼級模塊化的產(chǎn)出。本身是一組具有一定內(nèi)聚性代碼的組合,職責(zé)明確。對外的接口可以是松散的,也可以是集中的。SEI的定義為:提供一組 連貫的職責(zé)的軟件的實現(xiàn)單元。它以問題分解的形式,來解決軟件設(shè)計問題。它更強調(diào)一個內(nèi)聚的概念,形式上類似于Java語言中的包概念,也可以 是一個源代碼目錄(C語言也是)。
組件或者構(gòu)件(Component)使用比較廣泛,它的核心意義在于復(fù)用,相對模塊,對于依賴性有更高的要求。概念上與模塊基本等同,只是明顯有依賴性 的要求。(早提出時概念)。
6.2 Unity的組件化應(yīng)用
Unity的設(shè)計把組件化的軟件工程設(shè)計思想進行了充分的發(fā)揮,Unity環(huán)境內(nèi)置了打包器(Packer)和解包器(Unpacker),技術(shù)開發(fā)人員可以將自己 制作的插件打包成.unitypackage的格式,然后進行網(wǎng)站上的發(fā)布供其它開發(fā)人員導(dǎo)入。
圖 10 臉譜的Oculus VR產(chǎn)品
比如說,Vuforia是一款由Qualcomm推出的AR應(yīng)用開發(fā)工具,能將現(xiàn)實世界物體轉(zhuǎn)變?yōu)榛芋w驗的擴增實境平臺,旨在幫助開發(fā)者打造全新級別的真實 世界物品與虛擬物品的互動。Vuforia SDK可以通過官方網(wǎng)站進行下載(圖中的vuforia-unity-6-0-117.unitypackage名稱),開發(fā)者能夠在Unity的 環(huán)境下,通過下圖中的菜單彈出窗口將該軟件包導(dǎo)入項目選項卡窗口中去。與此同時,也將解壓后的很多資源文件導(dǎo)入了項目。
7 可擴展性設(shè)計
7.1 概要思路
可擴展性設(shè)計與實現(xiàn)是軟件工程所倡導(dǎo)的重要設(shè)計原則之一。若要完美地達成設(shè)計目標(biāo),需要與面向?qū)ο蟮脑O(shè)計、模塊化或組件化的設(shè)計思維、設(shè)計 模式等軟件設(shè)計思想結(jié)合起來進行充分的運用和發(fā)揮。面向?qū)ο笤O(shè)計的OCP(開-閉原則)設(shè)計原則,就是一個很好的例證。在C++類庫實現(xiàn)的過程中, 公開的接口和封閉接口的需要針對用戶的取得平衡。軟件功能模塊劃分的“緊內(nèi)聚,松耦合”,通用的部分做成平臺模塊,不同盡量實現(xiàn)成可配置模 塊。還有設(shè)計模式當(dāng)中的適配器模式等等,所有都很好地體現(xiàn)了可擴展性設(shè)計的思路。
7.2 Unity的可擴展性體現(xiàn)
7.2.1 Unity的Gizmos
Unity的Gizmos類可在Scene視口中繪制圖像用來顯示設(shè)計細節(jié)。利用Gizmos.DrawIcon函數(shù)可以在場景視口中繪制一個圖標(biāo)以標(biāo)記特殊的對象和位置。 該函數(shù)使用的圖像文件需要位于 Gizmos中。
下圖中,Unity開發(fā)環(huán)境中的Gizmos按鈕所涉及到的基于Gizmos類的繪制射線,線段,網(wǎng)格球體,實體球體,網(wǎng)格立方體,實體立方體,圖標(biāo),GUI紋 理,以及攝像機線框。但有些特殊的場景視圖,用戶只能夠自己編碼實現(xiàn)定制化的Gizmos類實例。
7.2.2 Unity的編譯擴展方式
再舉個例子就是Unity對腳本擴展的實現(xiàn)方式。
通常情況下,Editor 文件夾中的腳本主要用來擴展unity編輯器的功能方便開發(fā)。這些腳本將不會打包進終發(fā)布的游戲中。項目中可以使用多個 Editor 文件夾,但是該文件夾中的腳本不允許用當(dāng)GameObject對象的組件(Component)。Plugins 文件夾中存放用于擴展unity功能的插件(多為 C/C++寫成的原生動態(tài)鏈接庫(DLLs))。這些插件可以訪問第三方代碼庫,系統(tǒng)API以及其他超出Unity功能的模塊。
在unity開發(fā)中,有的時候定制項目文件夾以管理游戲資源,包括代碼資源。但unity保留了一些特殊文件夾用來做特殊用途,例如編譯順序。
Unity的腳本編譯有4個階段(phase),腳本處在哪個編譯階段取決于腳本所在的文件夾。如果你的一些腳本需要引用一些別的文件夾中定義的類,則 需要關(guān)心他們的編譯順序。你引用的類需要先于你的當(dāng)前類編譯;蛘弋(dāng)你需要引用其他語言的腳本時,那么該腳本必須處于更早的編譯階段。
Unity中的4個編譯階段如下(類似于X Windows應(yīng)用對資源文件的查找方式):
1.處于 Standard Assets, Pro Standard Assets 和 Plugins 文件夾中的運行時腳本(Standard Assets 文件夾需是Assets的一 級子文件夾);
2.處于 Standard Assets, Pro Standard Assets 和 Plugins 文件夾下的以 Editor 命名的一級 子文件夾中的腳本;
3.頂級 Editor 文件夾中的腳本;
4.其他 Editor 文件夾中的腳本(例如其他文件夾下的以 Editor 命名的子文件夾) 另外在 Assets 文件夾中以 WebPlayerTemplates 命名的頂級子文件(即Assets/WebPlayerTemplates)將不會編譯。若是處于別的文件夾下的 WebPlayerTemplates (如Assets/Scripts/WebPlayerTemplates)將不會防止編譯。
8 面向?qū)ο蟮脑O(shè)計
8.1 面向?qū)ο笤O(shè)計思想
眾所周知,封裝、繼承和多態(tài)是面向?qū)ο笳Z言設(shè)計的三大原則。微軟在早期的Visual C++版本就支持了通過類繼承機制構(gòu)建的龐大MFC類庫,如今 的.Net類庫包含了這種思想。如今流行的C++,Java,Python,Ruby等程序設(shè)計語言都支持面向?qū)ο笏枷氲某绦蛟O(shè)計思想。
8.2 Unity的類庫實現(xiàn)
下圖Unity的類庫遵照典型的類層次關(guān)系圖,圖中的符號含義如下:
所有類的抽象基類Object,游戲場景中所放置的所有游戲?qū)ο蠼詮拇祟惱^承而來,有點類似于蘋果系統(tǒng)中的NSObject (面向?qū)ο驝的基類)。Unity開發(fā) 工程中涉及用到的動畫、攝像機、燈光、腳本行為、粒子渲染、碰撞器、剛體、變換、材料、網(wǎng)格、著色器和渲染器等等均按照類的繼承和組合關(guān)系 實現(xiàn)的。
9 結(jié)論
本文試圖帶領(lǐng)初涉Unity開發(fā)的技術(shù)人員或工程師,站在軟件工程設(shè)計和實現(xiàn)的角度,從多個視角挖掘和體會一下Unity集成開發(fā)環(huán)境中所蘊含的思想 ,為技術(shù)人員更好的利用該環(huán)境進行各個領(lǐng)域的開發(fā)打下良好的工具使用基礎(chǔ)。
供讀者參考資料:
[1] https://en.wikipedia.org/wiki/Interactive_programming
[2] //baike.baidu.com/item/Ruby/11419
[3] https://www.ruby-lang.org/zh_cn
[4] //www.ibm.com/developerworks/cn/java/j-lo-Singleton/index.html