關於Unity 2018的實體組件系統(ECS)一

孫廣東  2018.5.19html

 

 

首先來自ECS的概念。git

 

什麼是ECS?github

首先什麼是ECS? ECS是一種新的架構模式(只是在Unity中算新)。網絡

總之,這是一個(做爲目標)取代GameObject / Component 的模式。 其模式遵循組合優於繼承原則,遊戲內的每個基本單元都是一個實體,每一個實體又由一個或多個組件構成,每一個組件僅僅包含表明其特性的數據(即在組件中沒有任何方法)。系統即是來處理擁有一個或多個相同組件的實體集合的工具,其只擁有行爲(即在系統中沒有任何數據)。架構

實體與組件是一個一對多的關係,實體擁有怎樣的能力,徹底是取決於其擁有哪些組件,經過動態添加或刪除組件,能夠在(遊戲)運行時改變實體的行爲。工具

 

ECS旨在比GameObject / MonoBehaviour更容易處理大量物體。性能

 

ECS的特色是,因爲面向數據的設計 , 很容易並行高速處理,和 C# Job System 一塊兒工做。測試

 

Unity技術演示, 移動大量對象優化

 

啓用Burst編譯器時的性能差別,能夠與ECS結合使用動畫

 

 

如今已經提供了只有基本功能。例如沒有剛體系統或動畫系統,甚至沒有體面的渲染器。大多數實現須要由你本身完成。

可是,若是功能可用,性能比GameObject好 。

 

 

順便說一句,配合C# Job System, 可使CPU利用率接近100% 。

 

 

如下是 (未優化) 性能結果比較。 傳統的腳本OC, C# Job System, Entity Component System, 和ECS with Burst Compiler。測試從1.3萬對象到6.8萬個。

 

 

 

 

ECS術語

ECS有幾個術語。

例如,實體Entity,組件數據Component Data,組件系統ComponentSystem,組Group 等4項。

  • 實體Entity:像容器同樣
  • 組件數據Component Data:要存儲在實體中的數據(不包括處理)
  • 組件系統ComponentSystem:處理
  • 組Group:組件系統運行所需的ComponentData列表

 

還有不少其餘的東西,可是目前這四個內容最重要。

 

它與 起源(傳統)ECS術語略有不一樣。

  • Entity=Entity
  • ComponentData =Component
  • ComponentSystem = System

 

 

在這個術語中,與Unity的GameObject /Component相比,有一個稍微接近的地方。若是徹底粗略地說明,則它與如下項目匹配。

 

  • Entity=GameObject
  • ComponentData =Component的字段
  • ComponentSystem =Component的Update方法
  • Group = 無

 

 

 

ECS與Component結合使用

Unity的GameObject和Component, 經過給GameObject 提供MonoBehaviour 來定義行爲。有一種狀況是使用一個Manager,並指示他們移動的功能

 

此外, 會有移動角色的組件。

例如,當一個名爲Move的組件移動時,Move組件是經過GetComponent訪問Transform獲得並移動該對象。

 

 

另外一方面,ECS的工做就是這樣:

  • ECS的行爲 (System系統)和數據 (Component組件)將分別實現。
  • Entity實體中存儲了多種類型的數據(Component組件)。
  • 若是存儲在對象(實體)中的數據(組件)知足本組請求的數據列表,則調用行爲(系統)。

 

MonoBehaviour有1:1的數據和處理,但在ECS中它處理的是 ComponentData的組合。

例如,ComponentData有Transform和 Move做爲一組,並經過Group請求系統進行移動 。

 

處理時,稱爲變換和移動的組件信息直接傳遞到系統。

 

像這樣,調用什麼樣的處理由System(和Group)的組合來決定,實體是在全部系統來匹配批處理。

以下表所示,可能很容易理解哪一種處理將起做用。

 

不管如何,ECS被定義爲ComponentData的組合......

 

補充

首先是實體,這是從EntityManager生成的。建議從頭開始使用ComponentData生成實體,但您能夠稍後添加它。

實體在遊戲中有不少像GameObject同樣的東西。在某種意義上,實體≈遊戲對象。

 

系統爲每一個實體執行處理。像下圖所示 。

在兩個系統的狀況下,若是組匹配,都會工做。這可能在一個線程中運行,有時由C# Job System並行化。

 

 

例1

 

例如,讓咱們考慮一個實體,它具備在碰到障礙物時簡單的前向右轉的功能。

考慮到表示此實體所需的ComponentData,它以下所示。

  • 座標
  • 前方障礙的距離
  • 運動方向

順便說一句,若是你想用這個參數來實現運動,能夠考慮下面的實現。

一、從「座標coordinates」和「運動方向direction」中查找「到前方障礙物的距離distance and obstacle 

二、若是「前方障礙物Obstacles in front of」小於某個值,則更改「移動方向direction of movement

三、沿「移動方向movement」方向移動「座標coordinate

 

 

我把它們放入系統中。

系統負責實現 檢查距離,更新方向, 更新座標。 由於這些都是行爲!!!!!

 

 

 

示例問題2

那麼,此次你想讓一個實體像「朝指定座標方向移動」那樣?

 

這個實體彷佛有如下ComponentData。

  • 座標
  • 指定座標
  • 運動方向

系統看起來像。

一、從指定座標座標中尋找移動方向

二、在移動方向的方向上移動座標

 

那麼,這是第二個系統,使用與例1中徹底相同的東西。 因爲請求組是相同的。

若是你很好地理解系統,系統在很大範圍內是很好的,可是它也使得實現更加麻煩。彷佛有必要考慮這裏的平衡。

 

 

ComponentData組合的補充

它是ComponentData的組合,但實際上能夠設置多個組。

例如,建立GameObjectEntity(只有一個)和Unit Entity(有不少)的組合,你能夠期待的十日或一次所有中止根據遊戲管理的狀況下該股的操做。

 

另外,ComponentData不包含任何特別的內容,它有時指定ComponentData僅做爲組的定義, 做爲一個熊。

例如,若是你想有一個特殊處理,「熊貓」和「熊」是熊,須要PandaComponentData出現。

 

 

您能夠對ComponentData進行添加,刪除,設置(覆蓋?)操做。也有點像遊戲對象

 

 

 

 

 

誰調用了ComponentSystem?

到目前爲止,有一點有趣的是「誰調用系統?」

定義後自動調用!!!!!應該是世界在調用吧1

可是調用順序,你也能夠控制。

 

 

 

 

 

 

 

 

實體之間的消息傳遞

實體之間的消息交換是不可能的。

 

若是要將消息發送到特定實體,而後用實體內容覆蓋ComponentData,則系統處於處理中。

 

 

 

 

 

 

補充

ECS並非面向對象的,因此不能很好地理解,並試圖在OOP的背景下去理解(經驗

「不知何故FOWA!好像不可能理解」,你可能期待着面向數據的設計,並且可能會更好。

 

  • 觀察者模式,能夠被用於在系統間發送事件。
  • 策略模式,算是ECS模式的基石。

 

 

 

其它連接 能夠更好的瞭解:

官方開源, 也有文檔可也查閱!

相關文章
相關標籤/搜索