Unity客戶端框架筆記二(元件實體開發模式的思考)
https://blog.csdn.net/langresser_king/article/details/46324977
Unity客戶端框架筆記二(元件實體開發模式的思考)
2015年06月02日 11:40:13 langresser 閱讀數:4315更多
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/langresser/article/details/46324977
Unity的Entity-Component-System實現的非常漂亮,非常靈活。很多文章也對這種元件實體的開發模式倍加推崇。因為它契合這麼一條規則:優先使用組合而不是繼承。
但是實際開發過程中,限制於我的個人能力,想實現一個同樣漂亮的基於元件的MMO框架是非常困難的一件事情。
這篇文章是個人開發過程中的一些思考,實際上,所謂漂亮的框架是因人而異的,並且不一定是必須的,能夠用自己熟悉的方式快速的完成專案的開發就足夠了。只要開發過程不會感覺彆扭,程式碼也不會把自己或其他人噁心到,策劃修改需求的時候不會罵娘,後期不會出現各種難以除錯的Bug,那麼就是漂亮的框架。
從理論上說,所謂ECS就是一個Entity,持有一組Component,然後通過一系列的System來維護排程元件之間的邏輯。元件之間是相對獨立的,最理想的方式是通過Event來進行訊息傳遞。從這點來說Unity已經實現的非常漂亮了,GameObject可以繫結任意的MonoBehaviour,指令碼元件有統一的入口,並且可以通過SendMessage傳送訊息,也可以通過GetComponent來獲取一個具體的元件,直接呼叫其函式。
我反編譯了一大堆線上手遊的原始碼,幾乎沒有完全依賴元件模式進行開發的,更多的還是依賴一套繼承體系來完成。這裡我自己的感覺就是偏底層或者邏輯獨立性非常強的功能適合元件模式,而邏輯互動非常複雜的情況,過分依賴元件模式想要達到“理想”的效果,反而會適得其反。
比如,理論上ECS中,Entity應該像GameObject一樣,只維護元件,不包含任何其他邏輯或者程式碼,所有需要排程的邏輯都應該放在System中,它會關注它負責的Component。 然而,在我看來,這樣反而切割了邏輯,在實際專案中,要麼很難做到這樣的分離,要麼會讓程式碼變得很散,難以維護。當查Bug的時候,不會因為這樣的程式碼分離變得輕鬆,反而會因為結構的散亂造成無從著手的情況。
再說元件之間的訊息通訊,當遊戲全部以元件方式來實現,並且元件之間通過訊息來完成呼叫或者引數傳遞。這樣的程式碼很難寫,並且很難維護。事件從哪裡丟擲的,誰應該接受這個事件,持有哪些引數,這些都很不直觀。雖然達到了靈活的效果,但是副作用也很明顯,程式碼中充斥著各種各樣的Event,很難通過簡單的檢視、跟蹤、除錯理清楚遊戲的脈絡。
《Domination》是這樣實現的,一個EntityController,裡面包含全部的元件,並且提供對應的介面。它可以通過對應的配置檔案決定建立哪個元件。而外部只維護一個EntityController,無論是Soldier還是Building,它都是一個Entity,只不過一個掛接的是SoldierAttackComponent,一個掛接的是BuildingUpgradeComponent,從而產生不同的行為。 這種實現方式給我一定的啟發,因為它某種程度上說是符合ECS的。但是不得不說這種實現方式也很奇葩,EntityController非常龐大,雖然它沒有維護具體的邏輯,但是單單是維護Component的介面就讓它的程式碼達到幾千行,更不要說它概念上的龐大了。
《永恆戰士3》的實現相對正統,是現階段我可以接受的元件模式。不過嚴格說來這已經不是元件模式,而是組合取代繼承的一種實現方式。它有一個ActionController,裡面持有各種各樣的Agent,如AIAgent AttackAgent MoveAgent等等,外部主要與ActionController進行互動,而內部則通過這些Agent分散程式碼和功能。
Unity官方出的遊戲《大天使》在我看來非常的Low。宣傳視訊很酷,但是實際遊戲玩起來很渣,無論是畫面表現,還是遊戲可玩性。不得不說,專業做遊戲的和專業做引擎的確實不是一個工種。就其程式碼來說,它作為Unity官方出品的遊戲,竟然沒有體現Unity最先進的生產力,這實在是Low爆了。它的尋路是A* Path Finding Pro,介面是NGUI,動畫是老的動畫系統Animation,程式碼組織上強烈依賴介面設計,一個Actor繼承自IBuffable IHealthable ITakeDamage等等介面,很正統,但是也沒有什麼亮點。
一些日韓排行榜霸榜的遊戲,如《白貓》《鋼鐵騎士團》,其實程式碼結構一點也不漂亮,一個StageObj有幾千行。從這點來說過分關注結構反而是沒有意義的,那麼多暢銷遊戲,其實實現的一點兒也不靈活。自己習慣,好用,就足夠了。
其他還有很多遊戲,不過基本上大同小異。除去一些奇葩的實現外,基本上都是通過繼承體系完成基礎的物件抽象,然後通過元件將物件中比較大或者獨立的功能抽離出來。如狀態機元件、AI元件、動畫元件、角色屬性元件等等。
另外,有一點是非常統一的,就是有限狀態機的使用,基本上所有的遊戲都是通過FSM來完成角色的狀態流轉的,ARPG尤其如此。少部分的遊戲的AI部分可能用到行為樹。幾乎沒有見過只通過行為樹,而不依賴狀態機控制角色的。在我想來,行為樹每次都要進行整棵樹的遍歷,無論是從設計上說,還是效率上說都不適合遊戲角色的行為描述。而行為樹所擅長的AI方面,一般簡單的遊戲通過狀態機來維護就足夠了。