動畫最佳化:關於 AnimationClip 的三兩事
在上一期《材質優化:如何正確處理紋理和材質的關係》中,我們針對“材質”在日常開發過程中會遇到的一些注意點和大家進行了分享。這些看似細小的知識點,很容易在大家的開發和學習過程中被疏忽掉,而長期的問題積累最終都會反映到專案的效能表現上。為此,我們將這些規則列出,並且以一個個知識點的形式向大家逐一解讀。
在本文中,我們將面向“動畫”這個方向,以UWA本地資源檢測中的檢測規則:“Compression != Optimal的動畫資源”和“AnimationState數量過高的AnimatorController”,來為大家簡單講解相關的知識點。我們將力圖以淺顯易懂的表達,讓職場萌新或優化萌新深入理解。
1、Compression != Optimal的動畫資源

在專案的實際執行中,AnimationClip資源是執行時載入頻率最高的資源之一。通俗地講,它包含了Unity動畫執行中所涉及的大量的例如骨骼關節位置,放大縮小,旋轉變換,時間關係等各類資訊,並以動畫曲線的方式進行儲存。
AnimationClip的壓縮格式決定了其包體大小、執行時佔用記憶體大小以及載入效率。目前,Unity針對AnimationClip提供三種壓縮格式:
Off——以Stream方式儲存動畫資料,但不做壓縮處理;
Keyframe Reduction——以Stream格式儲存動畫資料;壓縮方式上,使用關鍵幀縮減演算法(簡單來講,就是對去除關鍵幀前後的曲線進行比較,如果對應的曲線值的差小於容錯值/誤差寬容度,則去掉關鍵幀)
Optimal——Unity會使用啟發式演算法,從而決定使用Keyframe Reduction演算法進行壓縮(Stream格式儲存),或者使用Dense格式壓縮儲存動畫曲線。

針對這三種壓縮方式,基於我們曾經做對比試驗時的實際表現(詳情可參考:《Unity載入模組深度解析之動畫資源》),可以發現在載入耗時上,Optimal是三種方式內最有優勢的。

Off這個選項是Unity官方都不推薦的,這裡就不細說了。Keyframe Reduction的壓縮方法,是採用Stream格式儲存。動畫曲線包含時間和切線資訊,進行曲線插值。記憶體佔用會比Dense格式儲存稍大,在記憶體壓縮效果上不是最優選擇。

一個簡單的Stream曲線示意圖
而Optimal在壓縮方法上,會從Stream格式和Dense格式之間進行選擇。主要的差別是Dense格式不含有切線資料,所以記憶體佔用會更小。

一個簡單的Dense曲線示意圖
由此可見:Optimal壓縮方法雖然可能會造成動畫質量稍有降低的問題,但記憶體佔用是最低的,所以是我們最推薦的方案。
因此,在“優化”這個前提下,本條規則會找出所有不為Optimal的動畫資源,並且詳細標註出相應的壓縮型別;開發團隊需要依據記憶體效能和動畫效果的實際考量,去對這部分資源進行單獨的設定。

2、AnimationState數量過高的AnimatorController

首先我們先簡單理解一下Animation和Animator。這倆是Unity中兩套用來控制動畫播放的元件。Animation的存在時間更早,從使用上來講適合控制單個動畫資源。

Animator的出現時間較晚,但在控制多個動畫資源以及動畫資源間的切換上具有優勢。

然後我們再來說一下AnimationClip和AnimationState。AnimationClip我們在上面一條中簡單說了,它裡面包含了很多資訊,而每一個AnimationClip外都套著一個叫做“AnimationState”的外殼,包含了動畫片段的一些播放控制屬性。
關鍵來了:Animator元件通過“狀態機控制器”,也就是AnimatorController,來控制多個AnimationState,以此實現AnimationClip之間的切換。

比如實現“跑步—原地休息—爬樹—原地休息—跑步”這一連串的動畫動作,我們只需要將這幾個AnimationClip新增到Animator編輯器內即可。

UWA曾經做過相關的測試,結果表明:單個AnimatorController下掛載的AnimationState數量過大,會給CPU運算帶來一定的壓力,在進行開發時候,應該儘量控制AnimatioinState的數量。對此規則,我們給的預設閾值為30。
所以在篩選出這些“動畫狀態機中AnimationState的數量過多”的AnimatorController之後,開發團隊需要根據實際情況去判斷其合理性。
希望以上這些知識點能在實際的開發過程中為大家帶來幫助。需要說明的是,每一項檢測規則的閾值都可以由開發團隊依據自身專案的實際需求去設定合適的閾值範圍,這也是本地資源檢測的一大特點。同時,也歡迎大家來使用UWA推出的本地資源檢測服務,可幫助大家儘早對專案建立科學的美術規範。

我們已支援Luacheck功能啦~
我們已支援粒子特效檢測~
這麼多實用貼心的功能
你們還沒用起來嗎?
萬行程式碼屹立不倒,全靠基礎掌握得好!
效能黑榜相關閱讀
《那些年給效能埋過的坑,你跳了嗎?》
《那些年給效能埋過的坑,你跳了嗎?(第二彈)》
《掌握了這些規則,你已經戰勝了80%的對手!》
相關文章
- 自動化測試的三兩事兒
- 自動化測試的三兩事兒 (下)
- 關於敘事與故事:我眼中的《畫中世界》
- Android中關於Context的三言兩語AndroidContext
- 關於緩動動畫函式的封裝動畫函式封裝
- 關於Laravel的二、三事(1)簡單的路由Laravel路由
- AnimationClip同步工具
- 關於移動端網頁裡的畫素網頁
- 關於mysql的最佳化MySql
- 關於Cookie的那些事Cookie
- WPF兩種緩動動畫動畫
- 正規表示式兩三事
- 關於React中動畫不生效的一些思考React動畫
- 關於moment打包的那些事
- 關於 sudo 的那些事兒
- 那些年關於HTTPS的事HTTP
- 關於 const 最佳化。
- 【Android 動畫】動畫詳解之屬性動畫(三)Android動畫
- 關於Rollup那些事
- 關於 ulimit 的兩個天坑MIT
- 關於Laravel的二、三事(1)一次請求的生命週期Laravel
- 關於 Flex 的那點事兒Flex
- 關於 MySQL 的巢狀事務MySql巢狀
- 關於分散式事務的理解分散式
- 關於SCN需要知道的事
- 基於canvas的骨骼動畫Canvas動畫
- Apache Commons 3 比較物件三兩事Apache物件
- 關於技術文章“標題黨”一事我想說兩句
- 關於Flutter中的StatefulWidget小最佳化Flutter
- LeetCode第三題三部曲之三:兩次最佳化LeetCode
- [elixir! #0084] 關於 DFA(確定性有限自動機)的那些事兒
- 關於Select Model的兩篇譯文
- 關於自定義元件的那些事兒元件
- 關於前端架構師的二三事前端架構
- 關於 TCP 需要了解的事兒TCP
- 關於Git小白應該知道的事Git
- 關於國密HTTPS 的那些事(二)HTTP
- 關於mysqldump備份非事務表的注意事項MySql