博客 / 詳情

返回

DMotion - 基於DOTS的動畫框架和狀態機

【博物納新】專欄是UWA旨在為開發者推薦新穎、易用、有趣的開源項目,幫助大家在項目研發之餘發現世界上的熱門項目、前沿技術或者令人驚歎的視覺效果,並探索將其應用到自己項目的可行性。很多時候,我們並不知道自己想要什麼,直到某一天我們遇到了它。

今天推薦的項目來自UWA開源庫:
https://lab.uwa4d.com/Lab/62b...

一、簡介

自從Unity推出了DOTS(Data-Oriented Technology Stack,面向數據的技術堆棧)之後,關於其應用一直備受關注。雖然DOTS對性能的提升比較明顯,但是由於其不算低的門檻,仍然讓許多開發者難以上手。以動畫為例,截至目前的Entities 1.0版本仍然沒有官方的基於Entities的動畫解決方案。本文介紹的插件DMotion就提供了基於DOTS的動畫框架和狀態機,可以幫助開發者更便捷地使用DOTS製作動畫

二、功能概覽

DMotion的基礎是另一個開源項目Latios-Framework的Kinemation部分。這個項目使用DOTS建立了一些常用模塊的框架,包括物理、音頻、動畫等等,目前仍在頻繁更新中,對於希望學習和使用DOTS的開發者也可以作為參考,鏈接如下:
https://lab.uwa4d.com/Lab/5df...

由於Latios-Framework使用了另一種動畫壓縮方案,即使用了插件Animation Compression Library,這個插件雖然理論上可以用於移動端,但是目前還沒有進行相應的適配,因此DMotion目前只能在PC平台上使用。作者提到之後會考慮擴展到移動端上。

目前DMotion的主要功能如下:
Current Features (V0.3.4):

  • Fully Bursted Runtime
  • State Machine Visual Editor
  • Transitions: Boolean, Int, Enum And End Time
  • Simple API For Playing Clips Through Code (See Samples)
  • 1D Blend Tree
  • Animation Events
  • Root Motion (With Writegroup Support, If You Need To Override Default Behaviour)
  • Object Attachment
  • Support For Optimized And Non-Optimized Skeletons
  • State Machine Visual Debugging

之後可能會更新的功能:
Planned Features:

  • 2D Blend Tree (Cartesian/Freeform)
  • State Machine Override (A.K.A Animator Override Controller)
  • Substates
  • IK Support
  • Multiple Layers
  • Skeleton Masks

三、使用

Latios-Framework最新的版本(目前為0.6.4)已經支持Entities 1.0,但是DMotion還只支持Entities 0.51版本,因此安裝DMotion的Package之後需要安裝Latios-Framework的舊版本,建議使用0.5.8版本。

DMotion這個插件的使用整體上是比較簡單的,可視化程度高,作者提供了Sample和詳細的指導,需要使用代碼的地方都有例子可以參考。文檔鏈接如下:
https://github.com/gamedev-pr...

這裏只做一些簡單的介紹,比如最簡單地播放一個Animation Clip。

首先需要創建一個DMotion的Clip。

然後在Inspector界面中設置好要用到的Animation Clip。

再給需要播放動畫的對象添加對應的組件,在組件中做一些設置,添加需要使用的Clip,就可以播放動畫了。

點擊Play即可播放動畫。

動畫狀態機部分可視化程度很高,和Unity本身的動畫狀態機的使用方法很接近。

首先創建一個動畫狀態機。

創建一個新的狀態。

添加對應的Animation Clip。

兩個動畫狀態之間可以建立Transition。

Transition可以設置一些參數和條件。

這些內容都可以在文檔中找到,因此不再贅述。

四、實現原理

DMotion是一個基於DOTS的框架,這裏我們從播放動畫的代碼開始分析。

繼承IConvertGameObjectToEntity是為了調用Convert函數把GameObject轉化為Entity 。繼承IRequestBlobAssets是為了調用RequestBlobAssets,把Animation Clip轉化成DOTS支持的格式,這裏使用了插件Latios-Framework中的Kinemation部分,最終會轉化成一種BlobAsset,這是DOTS當中針對Streaming做了優化的二進制數據結構。

Convert函數的具體內容,把GameObject轉化為Entity並添加對應的Component。

使用RequestBlobAssets把Animation Clip轉化成BlobAsset的部分。在運行的時候,DMotion使用的代碼都是使用Burst編譯的。在System文件中的代碼是運行時對Entities的Component進行處理的部分,也就是ECS中的“S”,可以看到這些代碼都是使用Burst編譯的,並且使用了Job System。

可見DMotion充分利用了DOTS系統,可以預測到其性能表現應該是比較優秀的。

五、性能

首先介紹一下DOTS為什麼會比傳統方式更快。Unity推出的DOTS主要包括三個方面,分別是ECS、Burst Complier和Job System。Entities是遊戲中的事物,或者説是一些數據的集合。Components把與Entity相關的數據組織起來,Systems則是把Components的數據從當前狀態轉換為下一個狀態的邏輯。下圖展示了ECS的組織架構。

ECS架構在執行邏輯時,只會操作需要操作的數據。System在操作數據的時候只會收集它關心的Component數據,CPU運行時就會將這一整塊內存裝入高速緩存中,這樣就減少了Cache Miss次數,增加了緩存命中率,整體上提高了程序效率。此外現代CPU中使用的SIMD技術與這種數據密集的架構相性極好,可以進一步提高性能。

ECS模式更加適合現代CPU架構,因為它可以做到高效處理數據,而不用把多餘的數據字段存入寶貴的緩存從而導致多次Cache Miss。比如操作Unity對象的Position屬性,會把GameObject所有相關數據都加入緩存,浪費了寶貴的緩存空間。而如果在ECS架構下,將只會把Position屬性放入內存,節省了緩存空間,也一定程度上減少了Cache Miss。

這種數據結構很適合並行處理。Burst Complier是使用LLVM從IL/.NET字節碼轉換為高度優化的本機代碼的編譯器,與Job System一起生成多線程並行處理的代碼,充分利用SIMD,多線程操作充分發揮ECS的優勢。因此Unity的DOTS往往比傳統方式速度更快。

由於DOTS本身的特性,DMotion的性能表現比Animator更為優秀。在文檔中作者認為性能提升可以達到大約6倍左右,而我們的實際測試結果為大約快3倍左右。

測試環境:
平台:Windows 10 (10.0.19044) 64bit
Unity版本:2021.3.9f1c1
GPU:Intel(R) UHD Graphics 750/Direct3D 11.0
CPU:3.6ghz/11th Gen Intel(R) Core(TM) I7-11700K @ 3.60ghz
測試工具:UWA GOT Online

測試用例:
使用的Model如下,擁有5770個頂點和29個骨骼。

使用的動畫是行走的動畫,分別使用DMotion和Animator進行測試。

測試內容:
加載並播放了2500個帶有動畫的模型,測試幀率。

測試結果如下:
DMotion:
平均幀率為15.33幀

Animator:
平均幀率為5.5幀

可見在性能上DMotion相比Animator有一定提升,可惜的是目前還不適配移動平台。感興趣的同學可以關注這個項目的更新情況,也可以嘗試在其基礎上做進一步的改進。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.