當前位置: 華文問答 > 遊戲

怎麽看Unity 2021.2 在編輯器工作流上的改進?

2021-08-11遊戲

這裏介紹一下Unity編輯器核心功能最佳化上的最新動態。這些改進涵蓋了從資源匯入到遊戲的構建與部署等各個方面,可以幫助使用者在開發的每個環節實作快速叠代。

  1. Unity編輯器啟動時間最佳化

Unity 編輯器在處理大多數內容時,需要先將原始檔轉換為適用於遊戲或即時套用的格式。在資源匯入後,引擎會將這些轉換後的檔與相關數據儲存在 Asset Database(資源數據庫)中。這時,如果某個檔修改了磁盤路徑,Unity 會重新整理這個數據庫;如果指令碼經過了修改,則引擎會重新載入整個 C# 域。在專案部署到目標平台時,Unity 的構建系統將其打包成二進制檔,用於在目標平台上分發和執行。整個流程如下圖所示。

在所有這些步驟中,Asset Database 是實作可靠、高效能和可延伸匯入流程的核心技術。但除此之外,編輯器叠代時間還受許多部份的影響,包括匯入程式、壓縮工具、編輯器核心程式碼及構建管線。

鑒於 Asset Database 占用了主要的專案啟動流程,我們可以透過最佳化數據庫的程式碼來測試其實際影響。Unity的Asset Database 團隊的高級工程師 Javier Abud 和 Jonas Drewsen 合作使用一個包含 90 萬個資源的測試專案建立了一個基準測試框架,借此提出了一系列啟動時間的最佳化和改進。兩人還開發了一套自動化數據記錄工具,用於記錄數據庫對 Unity 編輯器效能的影響。

"有許多成果目前就在我們手邊,但有些時候我們也需要一些發散性思維。我們每周能在測試專案上減少大約 15 秒的啟動時間,這些最佳化接著會套用到 22 個真正的專案中進行驗證,以此來保證這些卓有成效的最佳化不會在真正的專案中適得其反,」Javier Abud 表示。舉例來說,團隊有效地減少了執行緒或排序時的記憶體分配,並推出了專案檔及資料夾並列處理的方法。在 Unity 2021.2 中,一個包含 90 萬個文本資源的專案其啟動時間成功從 3 分 36 秒減少到了 1 分 17 秒,而小型專案的啟動時間平均加快了 8.7%。

2. 模型和紋理在Unity編輯器中的處理速度提升

2.1 Import Activity(匯入活動)視窗

Javier 還開發了一個稱作「Import Activity Window」的新工具,可顯示出資源匯入的原因、匯入過程的耗時,以及可能作為依賴項被匯入的資源。

如果將編輯器的啟動流程以餅圖表示,我們發現模型和紋理的匯入通常會占有最大的比重。這裏,我們來嘗試匯入【Book of the Dead: Environment(死者之書)】 專案所有的紋理、模型、預制件和場景。

源數據(包括 346 種紋理、133 個模型、214 個預制件、6 個場景)的大小為 2.25GB。時間統計在配備 Windows 作業系統、AMD ThreadRipper 1950X(16 執行緒)和 SSD 硬碟的器材上完成上,測試分別比較了 Unity 2020.3.10、2021.1.9 和 2021.2 alpha(a19)。

在預設設定下,2021.2 alpha 匯入時間僅為 114 秒(相較 2021.1 快了 1.27 倍)。如果再啟用四個匯入程式形成並列資源匯入,匯入時間將縮短為 77 秒。並列資源匯入的設定可在 Project Settings > Editor > Refresh 下找到。

如果再到 Build Settings 視窗中啟用 Force Fast Compressor(強制快速壓縮)選項來減少叠代時間,所有資產的匯入時間將僅為 38 秒——相比於 2021.1 版整整快了 3.8 倍!整個最佳化不會改變紋理的大小或格式,而是用更少的運算生成了盡可能好的壓縮紋理像素。

2.2 模型匯入

最佳化團隊的 Richard Kettlewell 自進入 2021 年周期以來一致專註於加快模型匯入速度。「(該領域)有許多問題和相應的方案,但都並不顯眼,」他解釋說。「舉個例子,逐個為每個頂點分配記憶體在處理大型網格表面時速度會非常緩慢,而部份演算法可透過執行一個預處理通道來計算某塊網格所需的總記憶體,然後以塊為單位分配記憶體。此外,很多匯入流程都會處理檔的每個表面、頂點、動畫或材質。如果能將其拆分為獨立的部份再並列匯入,匯入速度便會有極大的提升。」

"我們還采用了更快的記憶體分配程式用於給匯入時的暫時性記憶體",他繼續說,「這給各個階段都帶來了些許速度提升。我們還要感謝所有在百忙之中分享問題模型給我們的藝術家們,如果沒有這些內容,我們就無法進行測試並最佳化!"

Unity 2021.2 現在可以為檔中的多個網格模型同時生成法線、切線和光照貼圖 UV。在測試中,某檔原先需要花 33 分鐘匯入(其中 30 分鐘耗費在生成光照貼圖 UV 上),而在最佳化後總匯入時間可被降低至 11 分鐘,減少 66%。包含多個網格模型的檔將受益於此最佳化,原本緩慢的匯入流程將有極大的速度提升。

我們還將其他模型匯入流程進行了多執行緒處理,包括:

  • FBX 動畫的匯入
  • 頂點緩存最佳化程式的執行
  • 網格三角變化(將多邊形轉變為三角形)
  • SketchUp 頂點處理
  • 2.3 紋理匯入的最佳化

    Quality of Life 團隊負責了紋理匯入部份的最佳化,繼續推進 2021.1 周期初期的既定目標。在 2021.2 中,團隊再一次更新了 ASTC 壓縮程式,進一步提速 30%,並提高其在不同 CPU 上的執行穩定性。另外,BC7 的壓縮速度約為原先的 2 至 3 倍。

    Build Settings 的 Force Fast Compressor(強制快速壓縮)選項也是團隊的最佳化舉措之一。Aras Pranckevičius 解釋說:「如果紋理質素並非特別緊要,你可以使用更為精簡的壓縮流程(‘Force Fast Compressor’),或者設定限制全域的匯入紋理大小。」 「如果我現在將 2GB 的紋理匯入成安卓 ASTC 格式,與原先的 20 分鐘相比,整個匯入流程可在 2 分鐘內完成,唯一的缺點是畫質的損失會稍微多一點。但它仍非常適合快速的叠代。」

    3. Unity編輯器開啟大型、扁平層級的場景將快 90% 以上

    場景根目錄(即層級檢視頂層的 GameObjects)通常會按順序儲存為一個相互關聯列表,因此其載入和合並會耗費不少效能。此前,場景在開啟時編輯器會依次將每個根物件添加到列表中。每一條目會在場景中載入時會被添加到列表中,而每個新 GameObject 都必須在列表裏新建一個條目。但現在,新添加的根物件將作為 dynamic_array 儲存,列表僅在需要時會進行排序並相互關聯。由此,編輯器開啟測試場景的時間可以減少 90%——從 17 秒減少到僅 1.45 秒。

    3.1 編輯器的小提升帶來效能最佳化的大勝利

    Performance Optimization 團隊的是 Unity官方幫助客戶與內部大專案最佳化編輯器使用的主力。隨著遊戲越來越大,原本幾秒鐘的等待可能會逐漸發展成一個大問題。

    Peter Hall 是 Unity 2021.2 中效能最佳化的主要負責人,在他的眾多速度最佳化方案中,其中一個是對大型場景物件拖拽與選取的流程最佳化。在內部的測試場景中,整個流程花費了 78 秒,作為最佳化的基準參考。「在 Profiler 中的數據記錄顯示,大部份時間都花在了從 GameObjectTreeViewDataSource.RevealItems 中呼叫來的 BaseHierarchyProperty::Find 上。函數會將層級中的所有父物件寫入到根目錄下,但物件僅會被逐條寫入。如果使用 IHierarchyProperty.FindAllAncestors,這段運算的耗時可降低到 50 毫秒左右,速度可提高約 1400 倍。」

    編輯器內還有其它地方也有了提升,執行大型專案的速度已經變得更快,比如新建材質快了 2 倍、場景物件全選快了 1.6 倍、復制/貼上遊戲物件快了 50%。

    3.2 Unity版本構建

    在進入測試和最佳化階段時,遊戲在器材上的叠代速度會變得非常關鍵。因此,Unity投入了大量的時間和精力來全面最佳化了軟件包構建管線。例如,Unity 2021.2 的 Scriptable Build Pipeline(可編程構建管線)與 Build Cache(構建緩存)執行速度有所提升。

    最佳化的一個主要重點在於讓執行版構建流程僅打包新添的改動,而非整個專案內容。我們最近就改進了 Unity 本身的構建方式,並將同樣的方法套用到了執行版構建和指令碼編譯中。由此,Unity 2021.2 Beta 測試版現在支持 Windows、macOS、Android、Linux 和 WebGL 的增量式版本構建,並支持 C# 指令碼方案的增量式編譯。這項改進將在未來逐步推廣到剩下的平台上。

    "Unity 在構建執行版時做了很多事情。首先,我們將所有場景、資源及遊戲管理程式序列化為數據檔來建立執行數據。該流程由原生 C++ 程式碼完成,"指令碼團隊的 Jonas Echterhoff 解釋說。"當數據建立完成後,我們再呼叫一個後期處理方法。每個平台都有各自的方法程式碼。後處理常式因平台而異,但一般都包含二進制執行檔和相關檔的復制與記憶體分配、IL2CPP 程式碼到原生數據庫的編譯、以及符合平台要求的資料壓縮和打包等。這種後處理邏輯便是新構建系統中新添的內容。" 新系統對每次構建的輸入輸出及相互間的依賴都有記錄,因此只會重新執行必須的構建步驟,並在可能時以多執行緒完成構建。

    3.3 Unity原始碼IL2CPP 速度提升

    全新的 IL2CPP 源碼加密功能可生成最少 50% 的程式碼。降低構建耗時與可執行檔的體積。由於加密方法稍有不同,新功能可能會輕微影響執行時效能,因此其最適用於減少團隊內部的叠代時間。

    在 2020.3 中,IL2CPP 便經歷過一次大修,使其能夠利用多核 CPU 來生成 C++ 程式碼,用於執行版的構建。IL2CPP 團隊的 Michael Voorhees 表示:「(IL2CPP)程式碼完成度較高,我們的修改工作也因此受到了諸多限制。我們不得不在庫中刪除大量的靜態欄位,然後根據拆分法(divide and conquer)將程式碼重構。我們還重構了內部 API 來適應並列和序列編譯模式,借此來降低新最佳化的套用風險。並且,我們還建立了耐用的壓力測試場景,再花約一個月進行有效性測試,直到並列編譯滿足成為預設編譯方法的要求。」多虧了核心硬件使用的提高和最佳化,IL2CPP 編譯時間在整個 2021.1 有了進一步減少。

    而在 2021.2 中,團隊著手將編譯中最為耗時的步驟——泛型集合的編譯並列化。Michael 表示:「為了開啟新局面,我們用自己的數據模型替代了 Cecil。這些改動,外加上許多其它的小最佳化,使得 IL2CPP 在 2021.2 中的編譯速度比 2021.1 快了兩倍。」

    構建速度有了巨大的改變,特別是對移動端開發者而言。舉例來說,最新的 2D 範例專案【Dragon Crashers】在 Unity 2020 LTS 中采用的是非增量構建法,如果指令碼有了改動,要為 ARMv7 和 ARM64 構建將耗時 91 秒。而在 Unity 2021.2 中,新的增量構建工具僅花了 44 秒,不到前者的一半。

    在 Unity 2021.2 技術更叠版中,AssetBundle 載入也更加高效,還有 Unity 在工作流改進上的未來計劃。

    大家可以在Unity技術專欄中檢視更多的資訊:

    https:// developer.unity.cn/proj ects/behind-the-scenes-speeding-up-unity-workflows