最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

RE: 從零開始的 Unity ECS 1.0.14 正式版 (2023 - 3年后的文章翻新)

2023-08-20 03:41 作者:ms2308  | 我要投稿

本文的目標(biāo)是在盡可能短的時(shí)間內(nèi)(15-30分鐘)帶你零基礎(chǔ)用?Unity ECS 實(shí)現(xiàn)一個(gè)最簡(jiǎn)范例。

0. 前言

近幾個(gè)月 Unity DOTS?終于迎來(lái)了官方聲明的 “Fully Released”(存疑)的正式版,突然想最近重新?lián)炱饋?lái)看看與3年前有多大不同,果不其然資料仍然寥寥無(wú)幾,大多是19年20年的嘗鮮筆記。不過(guò)畢竟需求推動(dòng)供應(yīng),ECS的“反人類”架構(gòu)確實(shí)難以在業(yè)余開發(fā)愛(ài)好者中推廣開來(lái),嚴(yán)肅工作者只有追求極致優(yōu)化的大廠,比如試圖在移動(dòng)端渲染數(shù)千實(shí)體的那種國(guó)戰(zhàn)氪金手游。

盡管如此,我仍覺(jué)得同畫面承載上千上萬(wàn)單位非??犰牛讵?dú)立游戲也可一展拳腳,比如類吸血鬼幸存者?總之是塊值得大家一起啃的骨頭,而且雖然我做出好活的可能性比較低,萬(wàn)一讀者中有高人呢?所以想趁最近沒(méi)事重構(gòu)一下3年前已經(jīng)過(guò)時(shí)的ECS嘗鮮文章,再次精簡(jiǎn)國(guó)內(nèi)外的一些碎片資源、以及不太好懂的官方文檔,以通俗易懂廢話少說(shuō)的方式解釋基礎(chǔ)并實(shí)現(xiàn)一個(gè)麻雀雖小五臟俱全的ECS Demo。

(另外,立志從臭貓區(qū)up主轉(zhuǎn)回技術(shù)區(qū))

關(guān)于ECS的概念、優(yōu)劣不再贅述,簡(jiǎn)而概之就是適用CPU吃緊的超量單位的大場(chǎng)景,但不適用個(gè)體有復(fù)雜邏輯的情況,例如AI、狀態(tài)機(jī)、物理、復(fù)雜動(dòng)作等(未深入了解,根據(jù)社區(qū)反饋總結(jié)),因?yàn)閷?shí)現(xiàn)起來(lái)繁瑣且資料不足。此外,即便正式版已經(jīng)出來(lái),也請(qǐng)做好同樣場(chǎng)景 ECS 要麻煩的多的心理準(zhǔn)備!

本文基于穩(wěn)定版Unity 2022.3.7f1,由于 Unity DOTS 改動(dòng)很頻繁,網(wǎng)絡(luò)中絕大多數(shù)教程與最新版本有大量出入,直接照搬會(huì)有很多坑(Console 里會(huì)出現(xiàn)非常多的 "已廢除"警告),所以最新版入門避坑也是本文的另一個(gè)目標(biāo)。

1. 安裝

注意:根據(jù)官方論壇討論,當(dāng)前且未來(lái) DOTS 版本似乎僅支持 URP 或 HDRP,不再支持默認(rèn) RP。

Window -> Package Manager,安裝Entities和Entities Graphics,如果內(nèi)置的列表中找不到,在左上角+處URL添加:com.unity.entities、com.unity.entities.graphics。此外還須安裝Burst(默認(rèn)應(yīng)該已安裝)。


2.?ECS 基礎(chǔ)

本章將展示一系列?GameObject 與 ECS 實(shí)體的轉(zhuǎn)換和交互方式:

  • 如何簡(jiǎn)單生成 ECS Entity(實(shí)體)

  • 如何為實(shí)體添加儲(chǔ)存數(shù)據(jù)的?ECS Component(組件)

  • 如何通過(guò)腳本將 GameObject 轉(zhuǎn)化為 ECS 實(shí)體的 Authoring(編寫器)

  • 如何將 Authoring 組件轉(zhuǎn)化為 ECS 組件的 Baker(烘焙器)

  • 如何通過(guò) ECS System(系統(tǒng))處理組件中的數(shù)據(jù),使其進(jìn)行簡(jiǎn)單運(yùn)動(dòng)

  • 如何使 GameObject 與 ECS 實(shí)體交互

2.1. 在場(chǎng)景中直接轉(zhuǎn)化 ECS?實(shí)體

本段進(jìn)行基本場(chǎng)景設(shè)置,并用簡(jiǎn)單方式將?GameObject 轉(zhuǎn)化為 ECS 實(shí)體。

首先創(chuàng)建一個(gè)測(cè)試用新場(chǎng)景,再創(chuàng)建子場(chǎng)景(Subscene)進(jìn)行隔離,即右鍵 -> New Sub Scene -> Empty Scene...,所有在子場(chǎng)景中創(chuàng)建的 Game Objects 將會(huì)被自動(dòng)轉(zhuǎn)換為 Entities。

關(guān)于為什么使用子場(chǎng)景(翻譯自官方英文原文):

使用子場(chǎng)景(subscene)是因?yàn)閁nity的核心場(chǎng)景系統(tǒng)與ECS不兼容,將 GameObjects 和 MonoBehaviour 組件添加進(jìn) subscene 并進(jìn)行烘焙(baking),可將他們轉(zhuǎn)化為實(shí)體(Entities)和 ECS 組件。

右鍵點(diǎn)擊新創(chuàng)建的 SubScene ,創(chuàng)建一個(gè)測(cè)試用方塊 Cube (或任意用戶自己的 Prefab)。創(chuàng)建完注意?Inspector 的右上方有個(gè)小的空心圈,點(diǎn)擊后選擇 Runtime 便可顯示 ECS 實(shí)體已綁定的組件:

以前需要手動(dòng)綁定的基本組件,現(xiàn)在支持了自動(dòng)生成

2.2. 添加 ECS Authoring、Component 、Baker

接下來(lái)為物體添加一個(gè)“移動(dòng)速度”組件,使實(shí)體可以進(jìn)行勻速運(yùn)動(dòng)。

創(chuàng)建一個(gè) C# 文件(例如 Assets/Script/ECS/SpeedAuthoring.cs),Authoring 腳本用于引導(dǎo)?GameObject 轉(zhuǎn)化為 ECS 實(shí)體,Baker 在運(yùn)行時(shí)將 Authoring 組件的數(shù)據(jù)提取并轉(zhuǎn)換為ECS所需的 Component 數(shù)據(jù)。

注意:雖然每個(gè)類或結(jié)構(gòu)體一般單獨(dú)創(chuàng)建一個(gè)腳本文件,但項(xiàng)目到達(dá)一定規(guī)模后,會(huì)有大量的 ECS C# 文件(Authoring、Component、Baker等等),擠在一起難以管理,可以考慮將部分高度相關(guān)的多個(gè)文件合并為一個(gè)文件。

以下為 SpeedAuthoring.cs 中的代碼內(nèi)容:

首先我們將 Inspector 右上的小圈選擇回默認(rèn)(Automatic),對(duì) Cube 添加 Authoring 腳本,并寫入一個(gè)速度值:

添加 Authoring 腳本

再次選擇回 Runtime 模式,我們可以看到 Speed 組件及其數(shù)據(jù)成功被加入到了 Cube 的 ECS 組件里了:

2.3. 添加 ECS System

Unity DOTS 提供了兩種處理 ECS 實(shí)體和組件邏輯的方式:“托管類型” SystemBase 和“非托管類型”?ISystem。其中 SystemBase 繼承自 ISystem ,加入了很多便于開發(fā)的特性,但硬傷是托管類型無(wú)法被?Burst 優(yōu)化。ISystem 則兼容 Burst,相比 SystemBase 自然也快得多。

來(lái)自官方文檔中兩種模式的比較

詳細(xì)比較請(qǐng)參考官方文檔:https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/systems-comparison.html

總之雖然 SystemBase 方便,還是建議著重學(xué)習(xí)使用 ISystem。根據(jù)社區(qū)論壇開發(fā)者實(shí)踐,一些場(chǎng)景會(huì)相差數(shù)毫秒的幀處理時(shí)間(例如可能直接從30幀提升至120幀)。


2.3.1 SystemBase

通過(guò) SystemBase 可以相對(duì)簡(jiǎn)單地實(shí)現(xiàn)處理 ECS 實(shí)體中的數(shù)據(jù)。我們新建一個(gè) C# 腳本,命名為 MovingSystemBase.cs:

該腳本無(wú)需添加至任何 GameObject 中,因?yàn)?ECS System 默認(rèn)會(huì)將【所有】帶有 Local Transform 和 Speed 組件的實(shí)體都進(jìn)行移動(dòng)(x軸),運(yùn)行后應(yīng)能看到方塊會(huì)進(jìn)行移動(dòng),如果復(fù)制多份會(huì)觀察到所有都會(huì)同時(shí)移動(dòng)。讀者可嘗試復(fù)制極多單位、修改移動(dòng)模式等,觀察與普通模式下的CPU負(fù)載差異,后續(xù)將進(jìn)一步通過(guò) ISystem 實(shí)現(xiàn),一般最終都會(huì)達(dá)到數(shù)倍以上加速,故本文不再進(jìn)行量化的性能比較:

當(dāng)物體數(shù)量足夠多、且運(yùn)動(dòng)邏輯更復(fù)雜時(shí),性能提升會(huì)十分明顯
注意當(dāng)場(chǎng)景環(huán)境復(fù)雜且物體數(shù)過(guò)多時(shí),渲染可能會(huì)成為瓶頸,這部分無(wú)法僅利用?ECS 架構(gòu)解決

2.3.2?ISystem

接下來(lái)我們將上述邏輯通過(guò) ISystem 重新實(shí)現(xiàn),并補(bǔ)充引入兩個(gè)新技術(shù)使代碼邏輯更清晰:Aspect?IJobEntity。

我們先刪除或注釋上一段的 MovingBaseSystem.cs,新建一個(gè) MovingISystem.cs。

首先 ISystem 無(wú)法直接使用 Entities.Foreach,我們需要另辟新徑。在此之前,我們先引入一個(gè) Aspect?去封裝多個(gè) ECS 組件數(shù)據(jù)與函數(shù),否則當(dāng)組件越來(lái)越多時(shí),代碼會(huì)十分難看。


2.3.2.1 創(chuàng)建一個(gè) Aspect

我們可以新建一個(gè) C# 腳本創(chuàng)建這個(gè) Aspect,但因?yàn)樵诒?Demo 中,該 Aspect 僅服務(wù)于 MovingSystem,為了方便我們也可以把該類放在 MovingISystem.cs 中。

該 Aspect 將包括 實(shí)體編號(hào)(Entity)、本地位移(Local Transform)、速度(Speed)、移動(dòng)函數(shù) Move():

注意 RefRW 與 RefRO 標(biāo)記組件是可讀可寫還是只讀,盡可能使用只讀有利于性能提升。


2.3.2.2?創(chuàng)建一個(gè) ISystem

在 MovingISystem 中,利用剛剛創(chuàng)建的 MovingAspect,我們可以重構(gòu)移動(dòng)系統(tǒng):

引入 Aspect 后,代碼十分整潔,只需通過(guò) SystemAPI 索引具備 MovingAspect 的實(shí)體即可。但目前所有邏輯都執(zhí)行在主線程,接下來(lái)我們將 foreach 中的內(nèi)容封裝為?IJob,交給?Burst?去做大批量的函數(shù)調(diào)用優(yōu)化。


2.3.2.3 創(chuàng)建一個(gè) IJobEntity

因?yàn)槲覀円獎(jiǎng)?chuàng)建的 Job?需要遍歷 Entity,所以繼承 IJobEntity。將剛剛的 MovingISystem 更改如下:


2.3.2.4 Burst 編譯

最后我們?cè)?System 和 Job 前添加屬性?[BurstCompile] 為 Burst 編譯器進(jìn)行標(biāo)識(shí)(如想驗(yàn)證 Burst 編譯前后的差異,可以在 Move 函數(shù)中將位移重復(fù)進(jìn)行 1000 或 10000 次進(jìn)行觀察),System 的完整代碼如下:

使用 Burst 編譯時(shí)需要注意幾點(diǎn):

  1. 并行導(dǎo)致的一切問(wèn)題這里都會(huì)出現(xiàn),例如無(wú)法簡(jiǎn)單調(diào)用主線程或單例的函數(shù)等。

  2. 一切托管類型(Managed?Type),即以傳統(tǒng)的面向?qū)ο蠓绞骄帉懙念惡徒Y(jié)構(gòu)體,在這里均無(wú)法調(diào)用(例如 state.World),因?yàn)橥泄茴愋偷膬?nèi)存分配和釋放由.NET運(yùn)行時(shí)環(huán)境自動(dòng)管理。相對(duì)的,非托管類型(Unmanaged Type)是手動(dòng)管理內(nèi)存,可被 Burst 利用進(jìn)行優(yōu)化。

  3. 以上會(huì)造成不少開發(fā)上的難度,但實(shí)際并非一切運(yùn)算都要通過(guò)并行和 Burst 進(jìn)行優(yōu)化,可積極利用 Unity 自帶的一系列 Profiler 去定位性能瓶頸,好鋼用在刀刃上。

3. ECS 與傳統(tǒng) MonoBehaviour 交互

使用純 ECS 構(gòu)建一個(gè)完整的游戲難度極大,所以我們需要關(guān)心?ECS 實(shí)體如何與傳統(tǒng)的 MonoBehaviour 類進(jìn)行交互。

我們將實(shí)現(xiàn)一個(gè)基于 MonoBehaviour 的?Speed Manager,用來(lái)全局控制所有 ECS Entity 的速度。創(chuàng)建一個(gè) SpeedManager.cs 并掛到主場(chǎng)景的一個(gè)空 GameObject 上:

我們向 ECS 實(shí)體管理者 EntityManager 獲取所有帶 Speed 組件的實(shí)體,并保存在一個(gè)臨時(shí)實(shí)體數(shù)組中,然后我們遍歷所有的 ECS 實(shí)體,Get 它們的組件并 Set 速度值。通過(guò)類似方法可以輕松從外部批量修改 ECS 實(shí)體的組件數(shù)值。

執(zhí)行游戲時(shí),我們可以拖動(dòng) Speed Manager 中的 Global speed,觀察到所有的 ECS 實(shí)體會(huì)隨之運(yùn)動(dòng)。


以上我們便完成了最簡(jiǎn)ECS范例,不得不說(shuō)基本體驗(yàn)確實(shí)還是比三年前簡(jiǎn)潔優(yōu)雅得多,可以嘗試進(jìn)一步做一點(diǎn)有實(shí)際意義的小項(xiàng)目了。本文篇幅較短,實(shí)際仍有很多未涵蓋的點(diǎn),例如:

  • 如何寫 ECS 實(shí)體的 Spawner (發(fā)射大規(guī)模彈幕的需求)

  • 如何在實(shí)體內(nèi)實(shí)現(xiàn)隨機(jī)數(shù)生成器

  • 如何改變個(gè)體的材質(zhì)

  • 如何實(shí)現(xiàn)碰撞檢測(cè)與物理系統(tǒng)

  • 如何播放音效

  • 如何綁定 Animator

  • 如何實(shí)現(xiàn)多人模式

  • 與HDRP、粒子系統(tǒng)等的協(xié)同

未來(lái)一小段時(shí)間可能會(huì)進(jìn)一步地進(jìn)行嘗試,或許可以接觸到以上幾個(gè)方面,并結(jié)合一些物聯(lián)網(wǎng)技術(shù)開發(fā)一個(gè)小項(xiàng)目。如開發(fā)順利將會(huì)繼續(xù)補(bǔ)充?ECS 開發(fā)攻略。

RE: 從零開始的 Unity ECS 1.0.14 正式版 (2023 - 3年后的文章翻新)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
灌云县| 清远市| 佛学| 郑州市| 瑞安市| 惠来县| 新津县| 临夏市| 江城| 通化县| 综艺| 广饶县| 安顺市| 通道| 修文县| 祥云县| 新绛县| 慈利县| 怀仁县| 南召县| 普兰店市| 广东省| 青岛市| 西宁市| 湖口县| 茶陵县| 株洲县| 南开区| 临城县| 佳木斯市| 临泉县| 如皋市| 寿阳县| 庄浪县| 临朐县| 兰考县| 祁门县| 行唐县| 澄城县| 东辽县| 东山县|