[Unity]執行時用AnimatorOverrideController動態載入動畫片段
專案中經常會遇到這種情況:很多模型動畫的AnimatorController是一模一樣的(比如人類男,人類女),但是由於在AnimatorController中需要為每個State指定具體的Motion(比如人類女的Run和Attack要分別指定Human_Female_Run和Human_Female_Attack,如圖1),我們並不能簡單地在編輯器中給它們指定同一個AnimatorControllor,否則如果人類男用了人類女的AnimatorController我們就會發現人類男走起路來也一扭一扭的了=_=|||(原因是決定骨骼動畫的Avatar資訊儲存在這個Motion所指定的AnimationClip中)
圖1
要解決這個問題就要用到Unity的AnimatorOverrideController了,先貼個API手冊: https://docs.unity3d.com/ScriptReference/AnimatorOverrideController.html
程式碼如下:
private readonly string PrePath = "Prefabs/AnimationClips/"; private readonly string[] ActionList = {"Run", "Attack"}; private Animator m_animator = GetComponent<Animator>(); [HideInInspector] public string m_modelName; //... if (m_animator != null) { AnimatorOverrideController overrideController = new AnimatorOverrideController(); overrideController.runtimeAnimatorController = m_animator.runtimeAnimatorController; foreach (var actionName in ActionList) overrideController[actionName] = Resources.Load(PrePath + m_modelName + "_" + actionName) as AnimationClip; m_animator.runtimeAnimatorController = overrideController; }
這裡主要需要注意的是
1. Resources.Load()的是以"模型名_動作名"格式命名的.anim檔案,比如模型名是"Human_Female",動作名是"Run",那動畫檔案就是"Human_Femal_Run.anim".
2. overrideController中儲存的是當前animator中所有用到的動畫片段. overrideController[actionName] 的actionName是動畫片段的名字,而不是State名字,即圖1紅框中的部分.我們並不對State進行任何操作,包括Motion中指定的動畫片段的名字也不改變.因此建立AnimatorController的時候,需要先隨便給每個State的Motion指定一個名字為actionName的動畫,保證overrideController[actionName]存在,然後我們再用自己的AnimationClip去替換它.拿剛才的人類男和人類女舉例來說,就是需要先給Run這個State指定一個名字為Run的動畫,Attack這個State也要指定一個名字為Attack的動畫.這裡隨便用誰的動畫都可以,因為我們這裡只是為了"讓Dictionary中存在這個Key",以便後面我們用上述程式碼來替換.另外有一點要注意的是
overrideController[actionName] = Resources.Load(PrePath + m_modelName + "_" + actionName) as AnimationClip;
這句會把所有State中的同名動畫片段都替換掉.
3.這裡把每個動作單獨作為一個anim儲存而不是統一存在一個FBX中讀取的原因是Unity現在還不能在執行時建立Animation(圖2是16年2月Unity論壇的官方回覆,後面我也沒有找到新訊息說支援了).
圖2
4. 這種方法儲存出來的帶animator的prefab的動畫在編輯器中看會是錯的,因為此時還沒有載入正確的animator controller,想看正確的動畫需要看最原始的FBX檔案
P.S.從FBX中提取單一anim的方法:當把FBX截取出Clips之後
在Project檢視中點開FBX後面的白三角就會出現這些動畫片段,單擊想要提取的anim然後按ctrl+D(即Duplicate)就會在同一資料夾下生成相應的anim檔案
本文中所用Unity版本為5.4.1f1