ECS
Entity、Component、System
- Entity
- Component
- System
模塊解耦
守望先鋒 https://gameinstitute.qq.com/community/detail/114516
從描述的狀態 Component 上,不同的觀察者會看見不同的行為,拆分不同System出來分別實現。
內存連續
通過合理組織數據利用 CPU 的緩存機制來加快內存訪問數據。
舉個例子,當在 Unity 中實時更新若干個 Monster 和 Player 的坐標時,往往是在 Update 中實現 transform.position = new Vector(1,2,3),即需要加載數據是 Position,但是卻把整個 Transform 數據加載進內存,更高幾率造成 Cache Miss;此外,對應 Monster 和 Player 的 Update 生命周期更是不可控,導致加載的數據不久后就失效,一定概率造成 Cache Miss。
上面例子中對數據的處理方式對 Cache 不友好,也對 CPU 訪問內存的時間局部性不友好。
Entitas
Component
-
Unity Component 包括數據和行為。
-
ECS Component 單純包括數據。
System
Entitas 中的 System 等價於方法。
System 存在以下四種類型:
System 類型 | 實現功能 | Unity 相似函數 |
---|---|---|
Initialize System | 初始化功能 | Unity Awake |
IExecute System | 每幀更新功能 | Unity Update |
Reactive System | 觸發式更新功能 | Unity OnCollider 等 |
TearDown System | 析構功能 | Unity OnDestory |
其中 Reactive System 比較特別,主要實現是通過 Group + Collector 組成,通過監聽特定 Component 來處理對應的 Entity,並且在之后清除對應的 Entity,避免需要每幀處理大量數據。
Entitas 跟 Unity 交互
Unity 通過腳本構建對應的 Entity,並添加對應的 Entity Component 來傳遞消息,經過 Entitas 處理數據后通過監聽函數返回 Unity。
錄像回放機制
由於 Entitas 本身是嚴格時序控制,調用方在保證浮點數誤差,隨機數等一致的情況下,對於同一個輸入源,其輸出結果也是一致的。
因此記錄輸入源即可模擬整個運算過程,有些類似魔獸爭霸3的錄像機制。
性能
通過圖片可以看出,Entitas 在性能上要優於 Unity。
- reactive 標簽表示通過開啟 Reactive System 處理。
- non reactive 標簽表示不通過 Reactive System 處理。
- Job System 標簽表示通過開始線程處理。
關閉 Reactive System
Entitas 中如果某個 Component 通過 ReplaceXXX 函數賦值,則 Reactive System 會收集到對應的 Entity,如果通過 XXX 直接賦值,則 Reactive System 不會收集到對應的 Entity,從而節省 CPU 處理消耗,但是在實際應用中,不會專門繞開 Reactive System。
對象池
Entitas 通過盡可能復用所有對象來提高性能,減少內存分配時間和碎片。
- 復用 Entity
- 復用 Component
- 索引 Components
- 索引 ComponentValue( EntityIndex )
- 復用 Groups
ECS 編寫模式為在 System 中處理一批相同 Component 類型的 Entity,導致每次處理某個特定值時,需要檢查全部相同類型 Component 的 Entity,因此引入 EntityIndex 以高效地定位擁有某個具體 Component 值的 Entity。
Job System
Entitas Job System 跟 Unity Job System 實現方式不一致,其中Entitas Job System 是通過手動開辟新的 Thread。