Unity DOTS简明教程
什么是DOTS
首先,先來了解下什么是DOTS?
DOTS是Data-Oriented-Tech-Stack,官方中文翻譯是:多線程式數(shù)據(jù)導(dǎo)向型技術(shù)堆棧。
它主要由三部分組成:
下圖是Unite2019的介紹截圖:
所以,DOTS是一套集合型的高效技術(shù)堆棧,整合了Job System(編寫多線程代碼)、ECS(編寫高性能代碼)、Burst Compliler(編譯生成高性能代碼)。通過使用DOTS可以讓Unity項(xiàng)目跑的更高效,在移動(dòng)平臺(tái)上可以表現(xiàn)為更高的fps,更低的電池消耗,更小的發(fā)熱。另外關(guān)于ECS可以查看本博客的另一篇簡明教程。
如何使用DOTS
(一)安裝環(huán)境
先確認(rèn)下版本,這里推薦最新Unity版本,博主這里用的是Unity2019.3正式版;
1.打開菜單欄-window->package manager,右側(cè)的Advanced下拉切換為show preview package(截至目前2020.2.9依舊是預(yù)覽版),安裝:Burst、Entities、Jobs、Hybrid Renderer(用于DOTS的渲染相關(guān))、Unity Physics(用于DOTS的高性能物理組件)
2.啟用Entity Debugger(調(diào)試器),菜單欄-Window-Analysis-Entity Debugger,可以自行拖拽窗口到合適位置方便查看調(diào)試信息;
(二) 創(chuàng)建一個(gè)簡單實(shí)例
(1)創(chuàng)建子場(chǎng)景:新建一個(gè)場(chǎng)景,創(chuàng)建一個(gè)Cube,移除Box collider組件,選中并右鍵New SubScene From Selection,當(dāng)然也可以自行創(chuàng)建一個(gè)空物體,掛載SubScene腳本。
創(chuàng)建后則會(huì)自動(dòng)在Assets下產(chǎn)生一個(gè)場(chǎng)景文件及對(duì)應(yīng)的緩存文件。可以在Assets下自行更改剛創(chuàng)建的SubScene的名稱,本質(zhì)上還是一個(gè)Unity Scene,不一樣的是Cube所掛載的父節(jié)點(diǎn),多掛了一個(gè)SubScene腳本而已,用于管理和標(biāo)記此場(chǎng)景是一個(gè)DOTS的SubScene。
在SubScene腳本下,可以進(jìn)行一些配置,包括對(duì)應(yīng)的場(chǎng)景、面板hierarchy 顏色,是否自動(dòng)載入場(chǎng)景,關(guān)閉和啟用編輯子場(chǎng)景,保存等。打開編輯時(shí),可以在SubScene節(jié)點(diǎn)下自由編輯填充其他內(nèi)容,可以參考project tiny 的小賽車項(xiàng)目,里面就將整個(gè)大地圖就被作為了一個(gè)子場(chǎng)景。關(guān)閉編輯時(shí),則整個(gè)子場(chǎng)景的子節(jié)點(diǎn)不可見,也不可編輯,被當(dāng)作一個(gè)GameObject。
打開子場(chǎng)景編輯后,查看Entity Debugger,點(diǎn)擊右邊的All Entities(Editor World)可以看到當(dāng)前子場(chǎng)景的一些狀態(tài)信息,參考(一)2.圖
(2)編碼
創(chuàng)建一個(gè)C#腳本,Rotate.cs,沒什么,就是一個(gè)結(jié)構(gòu)體,它將作為數(shù)據(jù):
using Unity.Entities; public struct Rotate:IComponentData{public float radiansPerSecond; }創(chuàng)建第二個(gè)腳本,RotateAuthoring.cs,主要作用是將GameObeject轉(zhuǎn)化為Entity:
using UnityEngine; using Unity.Entities; using Unity.Mathematics;using Unity.Transforms;public class RotateAuthoring :MonoBehaviour,IConvertGameObjectToEntity {[SerializeField]private float degresPerSecond;public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)????{????????dstManager.AddComponentData(entity, new Rotate { ratiansPerSecond = math.radians(degresPerSecond) });????????dstManager.AddComponentData(entity, new RotationEulerXYZ());????} }IConvertGameObjectToEntity接口用于將當(dāng)前的GameObject(Cube)進(jìn)行轉(zhuǎn)換為DOTS的entity,然后綁定數(shù)據(jù);
其中RotationEulerXYZ是transform的旋轉(zhuǎn),為了提高性能,DOTS里重寫了一套組件,將原來的Transform里的旋轉(zhuǎn)、位置、縮放等都單獨(dú)出來。
第三個(gè)腳本是RotateSystem,繼承自ComponentSystem,作用是做entity的行為驅(qū)動(dòng)。
using Unity.Entities; using Unity.Transforms; public class RotateSystem : ComponentSystem {????protected override void OnUpdate()????{????????Entities.ForEach((ref Rotate rotate, ref RotationEulerXYZ euler)=>????????{????????????euler.Value.y += rotate.ratiansPerSecond * Time.DeltaTime;});????} }Entities.ForEach用于遍歷當(dāng)前所有的entity,然后將數(shù)據(jù)賦值給entity進(jìn)行操作;
編寫代碼完畢,就將第二個(gè)腳本RotateAuthoring掛載在Cube上。設(shè)置DegresPerSecond的值為50:
運(yùn)行項(xiàng)目,cube開始旋轉(zhuǎn)。查看status:
(3)使用JobSystem進(jìn)行優(yōu)化
修改RotateSystem.cs腳本:
using Unity.Entities; using Unity.Jobs; using Unity.Transforms;public class RotateSystem : JobComponentSystem {private struct RotateJob : IJobForEach<RotationEulerXYZ, Rotate>{public float deltaTime;public void Execute(ref RotationEulerXYZ euler, ref Rotate rotate){euler.Value.y += rotate.ratiansPerSecond * deltaTime;}}protected override JobHandle OnUpdate(JobHandle inputDeps){var job = new RotateJob { deltaTime = Time.DeltaTime };return job.Schedule(this, inputDeps);} }主要變動(dòng)是將繼承改為了JobComponentSystem,增加了一個(gè)RotateJob,然后到OnUpdate中調(diào)用job;
(4)使用BurstCompile
在菜單欄中啟用BurstCompile
在RotateSystem代碼中的RotateJob結(jié)構(gòu)體上添加[BurstCompile]特性,需要using Unity.Burst;
[BurstCompile]private struct RotateJob : IJobForEach<RotationEulerXYZ, Rotate>{public float deltaTime;public void Execute(ref RotationEulerXYZ euler, ref Rotate rotate){euler.Value.y += rotate.ratiansPerSecond * deltaTime;}}(5)驗(yàn)證
開啟SubScene的編輯,并大量復(fù)制cube,3000個(gè)以上。保存子場(chǎng)景。運(yùn)行,開啟unity編輯器的Status來查看:
我們發(fā)現(xiàn),幀率依舊很穩(wěn)定,只是Batches飆高到了3359。我們也需要優(yōu)化掉:
(6)優(yōu)化Batches
在Project面板下創(chuàng)建一個(gè)Material,命名為cube,并勾選Enable GPU Instancing.
選中子場(chǎng)景的所有cube,并將材質(zhì)賦值到所有cube上。保存子場(chǎng)景,再次運(yùn)行,發(fā)現(xiàn)batches已經(jīng)獲得了優(yōu)化,幀率也大幅度提高。
小結(jié)
DOTS帶來的性能改進(jìn)是十分客觀的,可以想象一些彈幕游戲、塔防游戲,使用上DOTS是可以非常直觀的看到性能改進(jìn)的。目前Unity也在大力推這套開發(fā)技術(shù),相信未來會(huì)有越來越多的項(xiàng)目使用DOTS,并得益于DOTS.
總結(jié)
以上是生活随笔為你收集整理的Unity DOTS简明教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Alpha 测试与 Beta 测试:有什
- 下一篇: STM32 HAL库学习笔记4-SPI