Unity ECS 01 核心概念

原文:https://docs.unity3d.com/Packages/[email protected]/manual/ecs_core.html

ECS 組件

實體組件系統(ECS)架構將身份(實體),數據(組件)和行爲(系統)分開。 該架構專注於數據。 系統讀取組件數據流,然後對數據進行處理,將其從輸入狀態轉換爲輸出狀態,然後對這些實體進行索引(沒看懂)。

下圖說明了這三個基本部分如何協同工作:

原圖
在此圖中,系統讀取Translation和Rotation組件,將它們相乘(L2W = T * R),然後用結果更新相應的LocalToWorld組件。
雖然實體A和B具有Renderer組件,而實體C沒有。但是C不會影響系統,因爲這個系統不關心Renderer組件。
您可以設置一個系統,使它需要一個渲染組件,在這種情況下,系統就會忽略實體C的組件;或者,您可以設置一個系統來排除具有渲染組件的實體,這樣就忽略實體A和B上的組件。

原型

組件的不同組合方式稱爲原型。 例如,一個3D對象可能具有一個表示位置的組件,一個表示運動的組件,一個表示旋轉的組件和一個用於渲染的組件。 每個這種3D對象都對應一個實體,但是由於它們共享相同的組件集,因此ECS將它們歸類爲同一個原型:

原圖
在此圖中,實體A和B共享原型M,而實體C具有原型N。
爲了順利更改實體的原型,可以在運行時添加或刪除組件。 例如,如果您從實體B中刪除了Renderer組件,則它的原型就變成了N。

內存塊

實體的原型決定ECS在何處存儲該實體的組件。 ECS以“塊”分配內存,每個塊均由一個ArchetypeChunk對象表示。 一個塊始終包含同一原型的實體。 當一個塊滿了之後,ECS會爲同一原型創建的任何新實體分配新的塊。 如果添加或刪除組件,導致實體原型改變了,則ECS會將該實體的所有組件移動到其他塊中。

原圖
這種組織模式在原型和塊之間提供了一對多的關係。這還意味着,要找到具有某些組件的所有實體,只需要搜索所有的原型(通常數量較少),而不是搜索所有實體(通常數量更多)。
ECS不以特定的順序存儲塊中的實體。當實體被創建或更改原型時,ECS將其放入該原型的第一個有空餘空間的塊中。然而,塊仍然是緊密排列的:從某個塊中刪除實體時,ECS將塊中最後一個實體移動到空出的槽中。
具有共享組件的實體也決定着這些實體存儲在哪個塊中。同一塊中的所有實體對於任何共享組件都具有完全相同的值。 如果更改共享組件中任何字段的值(從而不再與其他實體共享這個值),則修改後的實體將移至其他塊,就像更改該實體的原型時一樣。 如有必要,就分配新的塊。
當一起處理實體的效率更高時,可以使用共享組件對原型中的實體進行分組。例如,Hybrid Renderer定義了RenderMesh組件來實現這一點。

實體查詢

要確定系統應該處理哪些實體,請使用EntityQuery。實體查詢在原型中搜索具有所需要組件的原型。您可以進行如下查詢:

  • All: 原型必須包含所有指定的組件。
  • Any:原型必須包含至少一個指定的組件。
  • None:原型不能包含任何指定的組件。
    實體查詢會返回符合需求的的塊列表。然後可以使用IJobChunk直接迭代這些塊中的組件即可。

任務(job)

要利用多個線程,可以使用[C#Job system]。 ECS提供SystemBase類以及Entities.ForEachIJobChunk.Schedule()ScheduleParallel()方法,以將數據傳遞到主線程之外。 Entities.ForEach是最簡單的使用方法,通常只需較少的代碼即可實現。 您可以用IJobChunk處理那些Entities.ForEach無法處理的更復雜的情況。
ECS按照你的系統所安排的順序在主線程上調度job。 在調度完job後,ECS會跟蹤哪些job對哪些組件進行了讀取和寫入。 讀取組件的job依賴於那些必須在這次讀取前對該組件進行寫入job,反之亦然。 job調度程序使用job的依賴性來確定哪些job可以並行,哪些必須按順序運行。

對系統的管理(System organization)

ECS先通過世界,然後通過來管理系統(system)。 默認情況下,ECS將使用一些預定義的組來創建一個默認世界。 它找到所有可用的系統,實例化它們,並將它們添加到默認世界中的預定義的模擬組中。
您可以指定一個組中對每個系統進行更新的順序。 組本身也是一種系統,因此您可以像其他系統一樣將組添加到另一個組中並指定其順序。 當前組中的所有系統會在下一個系統或組之前進行更新。 如果未指定順序,則ECS將指定一種確定的順序,而這種順序與創建系統的順序是無關的。 換句話說,即使您未明確指定順序,組內的每個系統也會以相同順序進行更新。
系統的更新在主線程上進行。 但是,系統可以使用job將工作分流到其他線程。 SystemBase提供了創建和調度作業的直接方法。
更多信息參考:組件更新順序

當你在Unity編輯器中創建你的遊戲或應用程序時,你可以使用GameObjects和monobehavior來創建一個轉換系統來將那些UnityEngine對象和組件映射到實體。有關更多信息,請參見創建Gameplay

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章