《守望先鋒》團隊在2017年的GDC上的一篇演講:《守望先鋒》架構設計與網路同步 ,讓ECS架構火了起來。

ECS是什麼

ECS,全稱是Entity Component System,即實體、元件和系統。據wiki,這三種概念的定義如下:

實體,一般用途的物件,可以用唯一ID來標識。

元件,是一組資料,可以是實體的一部分,也可以是實體和世界互動的中間資料(注意:沒有功能)。實體由若干元件組成的,否則它就是一個空盒子。

系統,基於實體中的特定元件來實現特定功能,但是系統是集中批次處理所有的實體的。

這樣描述還是很容易混淆,比如UE4裡面也有Actor和Component,和ECS有什麼區別呢?在UE4中,Actor也是由Component組成的,不過Component提供的是資料和功能的集合,所以在UE4中經常看到各種Component的繼承。

我對ECS的理解

ue4中的Actor與Component

而ECS架構中,元件除了沒有功能之外,相同型別的元件還是集中儲存的(同一個chunk內)。System每次執行時遍歷所有具有指定元件的實體,集中處理這些元件。

我對ECS的理解

unity ECS記憶體佈局

ECS的這種資料組織方式類似列資料庫,System類似無狀態服務。

ECS的優勢和劣勢

相比OOP方式實現的Component,ECS中相同元件的資料是連續的,System又集中處理這些元件,可以方便的利用CPU Cache,提升效率。

由於System處理的可能是幾個元件,ECS將元件儘量的最小化(否則會有很多資料冗餘),這樣就實現了資料的扁平化。同時,System間禁止相互呼叫,最大程度的實現瞭解耦。而OOP最被詬病的呼叫層次深,結構複雜等問題都被解決了。

ECS也有它的不足,眾多的component和system會帶來認知負擔,而且system之間可能存在優先次序,排定這些次序需要技巧。

System之間禁止呼叫,物件間的互動需要用到延遲處理的技巧。比如A攻擊了B,你只能先把A攻擊和相關資料記錄下來,等專門處理受擊的系統處理到B的時候再計算對B造成的傷害。那如果B對A有反彈傷害呢?還得再來一遍。

ECS的應用範圍

ECS在處理扁平化資料和邏輯有很大的優勢,比如移動、碰撞、渲染等,資料單純且集中,處理起來效率高。而對於技能、AI邏輯來說,需要用到的資料較多,互動物件也多,並不能充分利用cache最佳化,而技能的思考流程也是反直覺的。