用戶:Lijinyu25775/實體-組件-系統(ECS)
實體-組件-系統 (ECS)模式是一種主要用於遊戲軟件開發的架構模式。 ECS模式遵循組合優於繼承原則,使得在一個每個對象都是實體(比如敵人,子彈,車輛等)的遊戲場景中,定義實體具有更大的靈活性。每個實體由一個或多個添加其他行為或功能的組件構成。因此,通過添加或刪除組件可以在(程序)運行時改變實體的行為。這消除了關於繼承層次結構的深度(縱向)和廣度(橫向)的,難以理解、維護和擴展的歧義問題。一般的ECS模式實踐通常是高度兼容的,經常與面向數據的設計技術相結合。
歷史
1998年發行的遊戲《神偷:黑暗計劃》是公認使用ECS模式的最早的遊戲。[1]然而它的技術細節在其他的ECS模式實踐公開後很久才公佈。[2]
據2002年Scott Bilas在GDC大會的演講中記載,同年發行的遊戲《地牢圍攻》是第一個被詳細描述的ECS模式實現。[3]
Bilas的講話明確提到了現在成為標準的概念有:基於數據庫的組合模式,數據驅動模式不僅是屬性,組件是一個自包含項等。
在2007年,開發《閃點行動:龍之崛起》的團隊嘗試使用包括由Bilas/《地牢圍攻》提到的一些ECS模式設計;Adam Martin後來撰寫了一份ECS模式設計的詳細介紹,[4]其中包括一些核心術語和概念的定義。[5]特別是,Martin普及了一些思想,如各系統作為頂級要素、實體既是ID,組件既是原數據和在系統,而非組件或實體中保留處理代碼。
Unity引擎在2008年至2010年期間變得大受歡迎,使得他們對實體和組件的不同使用方式變得眾所周知並被廣泛應用。然而,Unity引擎並沒有正式描述他們的技術。除非另有說明,否則通常將ECS模式作為術語來指代Bilas在2002年公開的技術。
術語
當今廣泛使用的Martin的術語[5]:
遊戲中的例子
假設有一個繪圖函數。 它就是一個系統,它遍歷具有物理和可見組件的所有實體並描繪它們。 可見組件一般具有關於實體的外表(例如人類、怪物、火花飛行、飛箭)的一些信息;使用物理組件來知道要在什麼位置描繪該實體。
再如碰撞檢測系統。 它將遍歷具有物理組件的所有實體,單它不會關心實體的描繪狀態。 然後假設有一個場景,該系統將檢測與怪物相碰撞的箭,並在這種情況發生時生成一個事件。 碰撞檢測系統無需了解箭是什麼,或當另一個(不帶物理組件的)對象被箭擊中時要做什麼。
還有一個包含健康數據的組件以及一個管理健康的系統。 健康組件將附加到人類和怪物實體上,而不能是箭實體。 健康管理系統將訂閱碰撞產生的事件,並相應地更新健康狀態。 該系統還能夠不時遍歷具有健康組件的所有實體,並重新生成健康狀態。
實體設計
實體只包含一個ID和一個組件的容器。 思路是沒有遊戲方法被嵌入到實體中。 容器不必與實體物理上聯繫在一起,但要容易找到和訪問。
對每個實體使用唯一的ID是常見的做法。 這不是一個強制要求,但它有幾個優點:
- 可以使用ID而不是指針來引用實體。更強大的是,它允許不用指針來銷毀該實體。
- 它有助於外部保存狀態。當狀態再次加載時,不需要重新創建指針。
- 數據可以根據需要在內存中隨意傳播。
- 實體ID可以作為一個實體的全局標識被用於網絡間通信。
這些優點中的一些也可以用智能指針來實現。
缺點
ECS模式設計存在幾個問題。
內部系統間通信
在系統之間發送數據的常規方法是將數據存儲在組件中。 例如,可以定期更新對象的位置。然後該位置數據被其他系統使用。
如果有很多不常見的事件,一個或多個組件將需要很多標誌。系統將不得不在每次迭代監視這些標誌,這可能變得越來越沒有效率。解決方案可能是使用觀察者模式。 依賴於事件的所有系統都訂閱它。因此,事件觸發的動作僅當事件發生時被執行一次,而不必再需要輪詢處理。
實體間迭代的成本
在一些ECS架構中,一個基本思想是為所有實體提供一個大的列表。每個系統然後遍歷完整的列表,並僅選擇所需的實體。如果系統數量增加,或者實體數量很大,則所有系統的總迭代成本可能過大。
在另一些ECS架構中,每個組件類型都存儲在單獨的列表中,因此無論哪個系統對這些類型的組件進行操作,只是在默認情況下迭代他們關心的對象。 在這種常見的ECS架構中,所描述的缺點通過更有效地利用CPU指令和數據高速緩存而實際上成為主要的性能優勢。
優勢
依賴性的安全管理
ECS架構以非常安全和簡單的方式處理依賴關係。由於組件是簡單的數據容器,因此它們沒有依賴關係。每個系統為了操作相應的實體,通常會註冊一些該實體必須具有的組件。例如,渲染系統需要註冊模型組件,轉換組件和可繪製組件。然後,渲染系統將檢查每個實體,如果某個實體擁有全部註冊組件,則該系統將對該實體執行相應邏輯處理。反之,則此實體被系統忽略,即不需要處理複雜的依賴關係樹。然而,這可能是bug隱藏的地方,因為通過組件將值從一個系統傳播到另一個系統可能很難調試。將數據與邏輯分離不會有助於減少依賴性,而是通過適當的代碼設計來減少依賴性。您可以將數據從一個具有100個依賴關係的類移動到一個組件中,但這並不能解決依賴問題,而是使該類更難調試。如果需要將未綁定的數據綁定到既存的生命周期(的實體),則可以使用ECS模式。
組合模式
ECS架構使用組合技術,而不是複雜的繼承樹技術。實體通常由一個ID和一組綁定的組件構成。可以通過向實體添加正確的組件來創建任何類型的遊戲對象。這也可以允許開發人員輕鬆地將一種類型的對象的功能添加到另一種對象,而不會有任何依賴性問題。例如,玩家實體可以添加一個子彈組件,然後它將達到某些「bulletHandler」之類的系統的操縱的要求,而這可能導致該玩家被相應系統對其或其裝備進行破壞性處理。
參閱
引用
- ^ Leonard, Tom. Postmortem: Thief: The Dark Project. [19 January 2015].
- ^ Church, Doug. Object Systems. Chris Hecker's Website (Powerpoint). [19 January 2015].
- ^ Bilas, Scott. A Data-Driven Game Object System (PDF). [25 December 2013].
- ^ Martin, Adam. Entity Systems are the Future of MMOG Development. [25 December 2013].
- ^ 5.0 5.1 Martin, Adam. Entity Systems are the Future of MMOG Development Part 2. [25 December 2013].
- ^ 6.0 6.1 Entity Systems Wiki. [9 February 2014].