天天看點

Unity 元件

元件(Component)這個概念最早是在2005年《Game Programming Gems 5》的《Component Based Object Management》中接觸到的,當時感覺在設計上很實用。後來,發現Unreal Engine 3的一個重要的改進就是抛棄了以前的基于純派生關系的對象 模型 ,而轉為使用 基于元件 的對象 模型 。對于這種設計思想,Unity比Unreal貫徹的更徹底——一切皆Component。

那麼到底什麼是“基于元件”的對象 模型 ?它能夠解決什麼問題?

在傳統的設計中,我們一般會使用“派生”來描述對象之間的關系。子類通過派生父類,來獲得父類的功能。在設計遊戲對象時,會根據遊戲本身的需要而為遊戲對象添加各種功能支援,比如渲染,碰撞,剛體,粒子系統等等。這些通用功能為了能夠為各種派生類提供服務,都必須實作到基類中。這樣就導緻了遊戲對象基類變得非常龐大臃腫,即難使用,又難維護。

”基于元件“的對象 模型 就是把所有需要提供給遊戲對象的基礎功能都獨立成單獨的”元件子產品“(Component),一個具體的遊戲對象可以将它需要的功能子產品組合到一起使用。所有”功能“不再是父類中的接口,而變成子對象執行個體,為遊戲對象提供服務。這樣既保證了功能代碼的可重用性,又增加了整個對象體系的子產品化和靈活度。

在Unity中,GameObject除了作為Component的容器之外,基本上沒有其他功能。所有需要的功能都要通過組合Component來實作。腳本本身也是Component,用來在GameObject上通過控制其他Component來實作自定義的功能。雖然這些Component在實體上是完全并列的關系,但是他們之間還是會有一定的層次關系的。在設計一個遊戲對象的具體功能時,元件一般會被分為三個層次。

引擎的基礎元件

Unity本身提供的各種内部功能元件。比如渲染元件,實體元件,聲音元件等等。這些元件實作了所有引擎提供的基礎功能,會被腳本使用來組合進階功能。

子產品功能腳本元件

通過腳本實作的一些相對獨立的通用子產品功能的元件。這類 元件的設計 是腳本可重用的關鍵,需要仔細分析遊戲對象中哪些功能可以被獨立出來成為一個可重用的功能子產品元件,并且在實作上應該盡量降低與其他元件的耦合性。比如在設計一個角色遊戲對象時,需要為他設計換裝功能。換裝功能其實就是對顯示子對象進行分組管理,切換顯示狀态。這個功能相對獨立,與其将他實作到角色中,不如獨立成一個功能子產品元件。角色遊戲對象和其他所有需要換裝功能的遊戲對象都可以通過包含這個子產品元件來實作換裝功能。

子產品功能元件之間還可能有依賴關系,也就是一個功能子產品元件可能依賴與另一個功能子產品元件,進而在這個元件層次上形成更多的子層次。

高層的膠水代碼腳本

這些腳本用來真正将引擎基礎元件和子產品功能元件組合到一起實作最終遊戲對象邏輯。用“膠水代碼”來形容這些腳本非常的貼切,就是把所有這些子功能“粘”在一起。比如設計一個Player腳本,将所有需要的元件功能組合起來,實作一個玩家的具體遊戲邏輯。因為這一層次代表的都是最高層的遊戲行為控制對象,是具體的遊戲邏輯的“膠水”代碼,不會再為更上層提服務,是以本身的可重用性并不高。但是這些對象之間按照類型區分,往往會有一些功能上的重合,是以反而可以繼續使用派生關系來實作功能的重用。比如在Character中實作所有的基礎功能(這些功能又是通過組合基礎元件來實作的),而Player和NPC都從Character派生,來繼承所有Character的功能,并繼續實作自己特殊的功能。一個功能到底應該用元件實作還是用派生實作并沒有非常明确的界限,應該根據需要靈活運用。

在使用Unity的過程中,如果要實作的是demo級别的小工程,并不需要考慮很多,直接用腳本實作功能就可以了。但是如果要有效地組織複雜的工程,提高代碼的重用性,充分了解和合理的利用“基于元件”的對象 模型 設計思想還是很重要的。