关于DOTS的个人总结
? ? ? ? 網上已經有比較多的DOTS的資料了,這里就簡單介紹一下。DOTS,Data-Oriented Technology Stack (?數據導向型技術棧)的縮寫,是Unity退出的面向多線程編程的解決方案?,其包含了 C# Job System、Entity Component System (ECS) 、Burst等組件組成。這里推薦一個up做的比較系統的筆記來參考一下(https://www.yuque.com/dev666/rxitsg/chtnhs?感謝這位叫做dev666的博主的分享)里面有相當多的干貨資料,對DOTS的實現原理、具體使用、API等都有詳細的分析,感謝!
? ? ? ? 我主要還是看了ECS這一塊的東西,感覺比較適合開發包含大量重復性且著色器渲染一致模型的應用場景。ECS沒有了狀態,只有大量的實體(Entity),實體上的掛載的組件(Component),對組件進行操作的系統(System)。通過對實體添加對應的組件來標記實體可以具有的能力,然后通過系統來過濾指定一個或一組組件,間接賦予實體能力,已經跟傳統的面向對象不太一樣了。附上個參考圖
?
? ? ? ? 參照著這個項目做出了demo(https://www.yuque.com/dev666/rxitsg/lfdqbo),這是個純ECS的小游戲項目,場景不需要掛載任何腳本直接創建空場景就能夠運行,下面附上開發環境的配置情況
Unity 2019.3.0f6
Enities preview.33-0.0.12
Hybrid Render preview.13-0.0.1
Mathematics preview.20 0.0.12
Universal RP 7.1.8
在配置好開發環境后,unity可能會報以下錯誤
這是引用的插件找不了RenderPipeline的相關引用方法,并不影響程序使用,可以直接屏蔽掉引用了RenderPipeline.beginCameraRendering的代碼。(估計是ECS需要RenderPipeline但現版本的unity并沒有提供相關的類庫)
附上工程的下載路徑
鏈接:https://pan.baidu.com/s/1v3BqFsVU2Zza4FTDDZF-tA?
提取碼:0hnc?
工程的運行截圖
? ? ? ?這個demo可以說是純ECS實現的,沒有Mono的代碼,通過給實體添加組件并利用系統實現能力的形式,實現了UI顯示,輸入控制,球體創建與下落、碰撞檢測、得分判斷等等功能。
? ? ? ?再說明下這個工程需要注意的地方
? ? ? ?項目是使用了自定義的渲染管線,所以我直接下載了URP插件(想省事的話可以直接下載Core RP Library)需要手動創建Render Pipeline Asset文件并拖拽到project settings的Graphic上
? ? ? ? 直接創建空場景不需要Camera直接運行就能看到項目的運行,同時要把Game窗口設置成Free Aspect,因為里面的UI就是手動創建的,并不是使用UGUI
? ? ? ? 一個項目最好只包含一個ECS的項目,因為ECS大多數類都不需要掛載到場景中,很可能會重復定義引起混淆。
?
下面是關于ECS使用的個人總結:
1.Component可以置空當作TAG來用
public struct Player : IComponentData { }
public struct Ball : IComponentData { }
?
2.在方法頭中申明[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
即使不掛載場景也可以在運行時觸發
?
3.EntityManager的獲取方法
a.通過World.Active.EntityManager獲取
b.繼承ComponentSystem的類 可以直接調用EntityManager
?
4.
獲取單例
GetSingleton<Game>() 獲取單例的Component
GetSingletonEntity<Player>() 獲取單例的Entity
設置單例
SetSingleton<Game>(game)
?
5.
獲取Entity上的Component
Position playerPosition=EntityManager.GetComponentData<Position>(player);
增加Entity上的Component
EntityManager.AddComponent(visibleReadyUIQuery, typeof(Disabled));
刪除Entity上的Component
EntityManager.RemoveComponent(invisibleReadyUIQuery, typeof(Disabled));
以上三個可以對Entity、EntityQuery進行操作
?
6.篩選Query 一般在OnCreate中初始化
private EntityQuery query;
protected override void OnCreate()
{
query=GetEntityQuery(new EntityQueryDesc
{
All=new[]{},//必須同時都有的Component組
None=new[]{},//只要有了就會被排除的Component組
Any=new[]{} //只要存在任意一個Component就符合的組
}
);
}
All、None、Any都是ComponetType[]類型 ,則元素都是ComponentType.ReadOnly(Component)
GetEntityQuery也可以直接使用,不需要All None Any
GetEntityQuery(ComponentType.ReadOnly<GameOverUI>(), ComponentType.ReadOnly<Disabled>());
?
7.在ComponentSystem中的update里刪除Entity
PostUpdateCommands.DestroyEntity(entities[i])
?
8.遍歷query的結果操作
using (NativeArray<ArchetypeChunk> chunks = this.query.CreateArchetypeChunkArray(Allocator.TempJob))
{
foreach (ArchetypeChunk chunk in chunks)
{
?
}
}
?
9.獲取chunk里面的Enity或者Component
ArchetypeChunkEntityType entityType = GetArchetypeChunkEntityType();
NativeArray<Entity> entities = chunk.GetNativeArray(entityType);
?
ArchetypeChunkComponentType<Position> positionType = GetArchetypeChunkComponentType<Position>();
NativeArray<Position> positions = chunk.GetNativeArray(positionType);
?
10.ComponentSystem的執行順序在類頭申明
在指定的組里面運行
[UpdateInGroup(typeof(InitializationSystemGroup))] 初始化
[UpdateInGroup(typeof(PresentationSystemGroup))] 邏輯與運算
[UpdateInGroup(typeof(SimulationSystemGroup))] 圖形處理
自定義組
public class InputHandlingSystemGroup : ComponentSystemGroup { }
自定義組并規定它的執行順序
[UpdateInGroup(typeof(SimulationSystemGroup))]
[UpdateBefore(typeof(UpdateSystemGroup))]
public class InputHandlingSystemGroup : ComponentSystemGroup { }
?
待補充
?
總結
以上是生活随笔為你收集整理的关于DOTS的个人总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态规划解决最长公共子序列
- 下一篇: Canvas炫酷3D线条动画背景