0 前言
? ? ? ? 早些時間學動畫系統時的筆記,實際還沒學完,后續計劃會慢慢補全吧。
1 動畫
????????通常來說動畫都是動畫師來做的,不過Unity也能實現簡單的動畫效果。PS:官方文檔中,將動畫稱之為動畫剪輯。
1.1 創建動畫
????????首先在Unity中打開動畫窗口。點擊“菜單欄-Window-Animation-Animation”即可打開動畫窗口,但此時窗口內是空的,此時若想要創建一個動畫文件,需要先選中一個游戲對象。我們在場景中創建一個Cube然后選中,便可以看到在窗口內部出現一個創建按鈕,點擊創建即可,記得選好創建路徑。過程如圖:
之后我們就可以在Animation窗口中制作動畫,同時在我們剛剛創建文件的路徑中會生成如下兩個文件:
Cube Animation是動畫文件,就是我們接下來制作動畫所操作的文件,Cube則是一個動畫控制器文件,后續會講。同時Cube上也會自動掛載一個組件:
先無視此組件,在后面會介紹。
1.2 制作動畫
????????首先來看下Animation窗口,主要說明幾個常用部分。
此時在此窗口內,實際上就只是在編輯Cube Animation文件。
1.2.1 錄制動畫
????????錄制動畫是比較簡單的方式,在開啟錄制后,通過幀游標在不同時間處操作游戲對象,讓Animation記錄游戲對象的狀態,進而實現動畫效果。錄制方式如下:
可以看到在錄制時,我們一旦操作Cube,其被操作的屬性就會被記錄,且顯示在屬性窗口內。在我稍微拖動了下Cube,這時就在0時刻記錄了Cube的狀態(注意記錄的是我操作后的狀態,若起始不操作Cube,直接拖游標到后面操作,那么會自動將Cube最開始的狀態記錄到0時刻,同時在游標位置記錄我操作后的狀態),然后我將游標拖動到1s的位置,將Cube的位置調整到斜上方,Animation會自動記錄下狀態。之后結束錄制,進行播放就可以看到動畫效果了。
????????除了位置外還可以調節Cube的Rotation、Scale等等。對于不滿意的屬性,我們也可以手動去屬性窗口調整。這里不再過多介紹。
1.2.2 手動實現動畫
????????除了錄制外,我們還可以手動添加屬性,添加屬性在某一時刻的幀,然后調整這一幀屬性的值。可以移動、刪除幀等等。如下演示了這些操作:
圖中,我先是添加了Cube的Position屬性,然后在0時刻添加了一幀記錄起始位置,之后其自動給我創建了一個末尾1s處的幀,我將此幀往后拉了一些,大概在1.3s處,然后調整了Cube的位置,再在中間添加了一幀記錄當前Cube的位置,我先是通過鼠標右鍵添加(添加到鼠標點擊處),后來又刪除,重新通過添加幀按鈕添加的(添加到游標處),至此動畫創建結束。可以看到,非錄制狀態下,幀的添加是要我們自己手動添加的,不過我依然可以通過調整模型來自動記錄調整的屬性。
如何添加幀
-
鼠標右鍵添加:點到哪里添加到哪里,且注意左側屬性,在不同行可以只記錄特定屬性或屬性中的一個值,或者記錄全部屬性。換言之,我們看到的K幀窗口中的小點,即表示對一個屬性的記錄,圖中,最上面的點是表示所有屬性,第二個表示Position屬性,再往下則是每個單獨的屬性x、y、z。這些屬性鼠標左鍵是可以點擊選中的。如圖:
我是左鍵選中再操作的,實際可以直接右鍵操作,不用左鍵先選中。
-
鼠標左鍵雙擊:和鼠標右鍵添加一樣。
-
添加按鈕:只能在游標位置處添加,且會記錄全部屬性。
1.2.3 曲線K幀窗口
????????點擊窗口中的Curves即可切到此窗口。
上方依舊是時間,左側表示值的變化,不同顏色代表不同屬性。在屬性值變化的設置上相比于之前的表形式更加靈活一些,畢竟可以調整曲線。其他的跟之前的窗口沒太大區別。這里不過多介紹了,想用這種方式的話,上手操作操作基本就熟悉了。
1.3 動畫參數窗口
????????選中創建的動畫文件,即可在Inspector面板中看到相關參數:
1.3.1 Loop Time
????????勾選Loop Time表示,播放動畫剪輯并在到達結尾時重新開始。勾線后可設置如下屬性。
Loop Pose:無縫循環運動。
Cycle Offset:循環動畫在其他時間開始時的周期偏移。比如一個動畫的進度條是A→B,此時因為我們已經勾選了Loop Time,所以動畫進度條可以看成A→B→A,這個參數是則是用于調整動畫在A→B→A中的偏移的。假設動作是跳躍動作,A是蹲下,B是浮空,那么通過此參數就可以將整體動畫后移,讓B變為蹲下,讓A就變為浮空,需要注意是整個動畫整體上的偏移。如下,用了個比較明顯的動作:
可以看到,動畫在整個循環進度條中發生了偏移。
1.3.2 Root Transform Rotation
????????根轉換旋轉。PS:首先要理解下根運動的含義,在Animator窗口中有講到,可以Ctrl+F搜索下,先看下。(先看完根運動含義)這里先提前說下Bake Into Pose,其會將根運動烘焙到Pose中,可以理解為模型姿勢,烘焙后根運動的位移之類變化就會應用到模型身上,但僅僅是模型身上,不會對transform里的參數產生影響。演示,Animator窗口不應用根運動(若看根運動定義時沒繼續往下看完Animator窗口的介紹,就先忽略這點,等會看了就懂了),來查看Bake Into Pose的影響:
可以看到,在未勾選Bake Into Pose時,模型transform未發生位置變化,且動畫一直鎖定在模型位置不會發生視覺上的位置偏移。而在勾選后,transform依舊不會變化,但動畫在視覺上發生了位置偏移,這是因為根運動被烘焙到了姿勢當中。
Bake Into Pose(Rotation):將根旋轉烘焙到骨骼移動。若在Animator窗口中開啟了運用根運動,則勾選此選項會關閉Animator中運用根運動的影響,即動畫不會影響模型transfomr中的rotation,應用Bake Into Pose的效果。如圖,運用根運動,在勾選Bake Into Pose時模型transform未旋轉,然后去掉勾選后就開始控制模型旋轉:
Based Upon:根旋轉基礎。動作朝向。分為Origin和Body Orientation選項。用于控制動畫朝向的,前者使用動畫文件本身的朝向(一般使用這個),后者是讓動畫朝向與模型朝向(z軸朝向)一致。如圖:
Offset:偏移量。調整動作朝向的偏移量,對上面的Origin和Body Orientation都有效。如下:
1.3.3 Root Transform Position(Y)
- Bake Into Pose:作用同上。只不過這里是對Y軸的影響。
- Based Upon:垂直根位置的基礎。垂直位置定點。分為Original、Center of Mass、Feet。分別是使用源文件垂直位置,使用質心位置作為垂直位置,使用雙腳位置作為垂直位置。具體可以試一試,這里就不演示了。
- Offset:偏移量。控制垂直位置偏移。
1.3.4 Root Transform Position(XZ)
- Bake Into Pose:作用同上。只不過這里是對XZ軸(平面移動)的影響。
- Based Upon:水平根位置的基礎。水平位置定點。分為Original、Center of Mass。分別是使用源文件水平位置,使用質心位置作為水平位置。
1.3.5 Mirror
????????勾選后講動畫鏡像。
1.4 小節
????????說實話,我在介紹動畫的制作時也只是做了基礎的介紹。小細節的東西很多,但又很基礎,上手操作嘗試幾次基本就都知道了,所以這里沒有做過多的介紹。各位在學習時,多嘗試做幾個動畫,操作操作也就基本掌握了。
2 動畫控制器
動畫控制器是用于控制動畫的文件,可與代碼配合,實現控制動畫切換等功能。
2.1 小案例
2.1.1 模型與Animator
????????這里用的是Unity Chan模型(什么?你不知道Unity Chan是什么,那你現在知道了,She is my waifu),在資源商店就能找到,不過動畫的則是用的其他動畫,不是Unity Chan自帶的。首先給模型添加一個Animator組件,然后設置如下:
????????在講參數之前首先說一個概念:根運動。
????????根運動可以簡單理解為動畫本身的運動,這里強調的不是動畫的動作,而是動畫所帶來的的如位移、面向旋轉、高度變化這類變化。Unity中通過根變換來將角色的質心在Y平面上投影來匹配根運動,因此根運動可應用于Unity中的角色模型上。那么如何運用呢?有兩種方式,一種是Animator面板上的Apply Root Motion,還有一種是動畫參數窗口中的Bake Into Pose,這個在前面已經講過了,不過建議看完下面的Apply Root Motion之后再返回上面去看Bake Into Pose。
-
Controller:動畫控制器,等會就創建,
-
Avatar:模型骨骼,一般模型都會自帶自己的骨骼,這里使用的就是Unity Chan包中自帶的。
-
Apply Root Motion:是否使用根運動。若使用根運動,則會將根運動中的位移、面向旋轉、高度變化這些應用到角色模型上且會影響角色transform組件當中的數值。但前面說過在動畫參數窗口中的Bake Into Pose可以將根運動烘焙到動作中(烘焙到動作中角色也會位移、旋轉,但不會影響transform組件的數值),兩者都應用了根運動,也就是說兩者存在優先級問題。若勾選了Bake Into Pose則以Pose為準,即不會影響transform的值。另外,此Apply Root Motion選項也可以理解為是選擇從動畫本身還是從腳本來控制角色transform組件的位置和旋轉值。
-
Update Mode:此選項可選擇Animator何時更新以及應使用哪個時間標度(可以理解為時間速度)。
-
Normal:Animator 與 Update 調用同步更新,Animator 的速度與當前時間標度匹配。如果時間標度變慢,動畫將通過減速來匹配。
-
Animate Physics:Animator 與 FixedUpdate 調用同步更新(即,與物理系統步調一致)。如果要對具有物理交互的對象(例如可四處推動剛體對象的角色)的運動進行動畫化,應使用此模式。
-
Unscaled Time: Animator 與 Update 調用同步更新,但是 Animator 的速度忽略當前時間標度而不顧一切以 100% 速度進行動畫化。此選項可用于以正常速度對 GUI 系統進行動畫化,同時將修改的時間標度用于特效或暫停游戲。
-
-
Culling Mode:為動畫選擇的剔除模式。
-
Always Animate:始終進行動畫化,即使在屏幕外也不要剔除。
-
Cull Update Transforms:未顯示渲染器時,禁用變換組件的重定向、IK(反向動力學)和寫入。
-
Cull Completely:未顯示渲染器時,完全禁用動畫。
-
2.1.2 創建動畫控制器
如圖,在找個文件夾,在其內創建即可。創建后雙擊打開動畫控制器文件,即可打開Animator窗口。
將一個動畫文件拖到Base Layer窗口內,這里我找了一個人物模型的待機動畫Idle。
之后將剛剛創建的動畫控制器拖拽到Unity Chan身上的Animator組件上。
2.1.3 演示
運行。
可以看到,模型播放了待機動畫。
2.2 Animator窗口
????????首先,在Animator窗口內各種操作,比如鼠標左鍵、右鍵、滾輪、按下滾輪等等,以及什么快捷鍵之類的就不說了,太基礎的東西了,說不完,自己操作操作就什么都懂了。后續內容也同理,個別可能會提下。
-
動畫層級窗口:即左側窗口,與參數窗口共享一左側位置,會顯示不同的動畫層級,不同的動畫層級可以實現不同的動畫,層級之間可以相互覆蓋。可以實現在特定情況下讓某一層級動畫去覆蓋另一層級動畫,比如人物普通狀態與騎乘坐騎的狀態。
-
動畫層級:創建的動畫層級,點擊即可改變右側動畫窗口。
-
動畫窗口:用于控制各種動畫之間的關系。更準確說,窗口內的小方塊可以理解為“狀態”。
-
參數窗口:在此窗口內可以自定義參數,程序可借助于這些參數來實現動畫切換效果。
2.3 狀態參數窗口
????????點擊動畫窗口內的某一個狀態(小方塊),比如這里點擊Idle,在左側Inspector面板內就會顯示各種參數信息,如下:
-
Motion:動畫文件。
-
Speed:動畫速度。設置為負時,可以倒播。
-
Motion Time:動畫執行時間。
-
Mirror:是否鏡像動畫。只適用于人型動畫。
-
Cycle Offset:循環偏移量。
-
Foot IK:腳部IK。【】
-
Write Defaults:動畫是否寫回默認值。【】
-
Transitions:過渡。不同狀態之間可以過渡。
-
Parameter:需要在參數窗口內創建參數后才可使用,可實現相關屬性與參數的聯動效果。【】
2.4 動畫狀態機
官方文檔解釋
????????角色或其他動畫游戲對象通常具有若干不同的動畫,這些動畫對應于該角色或對象可在游戲中執行的不同動作。例如,角色可以在空閑時輕微呼吸或搖擺,在得到指令時行走,以及從平臺上跌落時恐慌地抬起手臂。一扇門可能具有打開、關閉、卡住和撞開動作的動畫。動畫系統(Mecanim)使用類似于流程圖的可視化布局系統來表示狀態機,從而控制需要在角色或對象上使用的動畫剪輯并對這些動畫剪輯排序。
????????嗯....實際就是動畫窗口內的東西,各個狀態與其之間的連接關系,結合層級、參數等控制,即為動畫狀態機。動畫剪輯就是我們最開始創建的動畫Animation。
2.4.1 過渡
????????在動畫狀態機內,宏觀來看,其狀態(小方塊)之間的切換可稱之為“狀態過渡”。過渡是需要連接箭頭的,點擊箭頭又有很多參數可調整,那么箭頭就可以稱之為“動畫過渡”。
2.4.2 默認狀態
????????如下圖動畫窗口,在其中創建了一個新狀態,可以發現新狀態與Idle狀態的顏色是不同的。
這是因為Idle是第一個創建的狀態,其為默認狀態,其會與Entry自動相連。默認狀態是游戲運行時,模型自動播放的狀態。若想更改其他狀態為默認狀態只需要右擊想要更改的狀態,然后設為默認狀態即可,如圖:
其他創建的非默認狀態想要播放,則需要與默認狀態連線或通過參數控制來轉換。
2.4.3任何狀態
????????Any State,表示所有狀態。若有一個狀態A是所有其他狀態都可以直接轉過去的,那么就可以將Any State與狀態A連接。
2.4.3 動畫過渡(連線)
????????各狀態之間的連線,后面會講。
2.4.5 控制參數
如圖,可用參數有四種,接下來介紹其一般用途。
-
Float:浮點類型。用于大于、小于時,切換狀態。
-
Int:整型。用于大于、小于、等于、不等于時,切換狀態。
-
Bool:布爾類型,具有持續性。當滿足ture或false時,切換狀態,在bool值未改變回來時,保持切換后的狀態。
-
Trigger:也是布爾,但不具有持續性。true時切換狀態(動畫),通常用于觸發式動畫,即觸發切換執行完動畫后,直接返回原先狀態。
那么我們如何使用控制參數呢?
????????我們角色目前身上是掛載有一個Animator腳本的,我們需要在腳本中獲得此組件來設置以上參數。但是在具體設置前,還需要現在Animator窗口中創建相關參數提供給我們使用。如下圖:
在圖中我在左側創建了四個參數(使用旁邊那個小+號),并將類型作為參數名,分別對應了四種參數,且面板上的值即為默認值,然后在狀態機里(動畫窗口,后續就稱狀態機了)加入了Walk狀態,并將Idle與Walk狀態相連接(右鍵狀態→Make Transition即可連接狀態。選中連線按下Delete可刪除),連線即動畫過渡。然后選中從Idle→Walk的動畫過渡(連線),在Inspector面板中可添加之前創建的參數。
選擇某一類型參數后,可設置條件,滿足條件即可執行當前的動畫過渡。Bool類型可選true、false。Float和Int都是設置超過或低于某一個閾值。Trigger沒有可設置內容。這里我們選擇使用Bool類型,將Idle→Walk設置為ture,Walk→Idle設置為false。之后創建一個腳本掛載到角色上,我掛載的腳本代碼如下:
using UnityEngine;public class ChangeAnimation : MonoBehaviour
{private Animator m_animator;//Animator組件private void Awake(){//獲取組件m_animator = this.GetComponent<Animator>();}private void Update(){//按下Q鍵if (Input.GetKeyDown(KeyCode.Q)){//設置參數Bool為truem_animator.SetBool("Bool", true);}//按下E鍵if (Input.GetKeyDown(KeyCode.E)){//設置參數Bool為falsem_animator.SetBool("Bool", false);}//m_animator.SetFloat(name, floatValue); //設置Float類型參數//m_animator.SetInteger(name, intValue); //設置Int類型參數//m_animator.SetTrigger(name) //設置Trigger參數,無值,調用此方法即達成動畫過渡條件}
}
之后運行程序按下Q、E測試效果:
可以看到,在按下Q后Bool變量轉為ture,狀態機切換為Walk狀態,模型播放走路動畫。在按下E后Bool變量轉為false,狀態機切換為Idle狀態,模型播放待機動畫。
2.5 混合樹
官方文檔解釋
????????游戲動畫中的一項常見任務是在兩個或更多相似運動之間進行混合。也許最熟知的示例就是根據角色的速度來混合行走和奔跑動畫。另一個示例是角色在奔跑期間轉向時向左或向右傾斜。 ? 區分過渡與混合樹十分重要。雖然兩者都用于創建平滑動畫,但它們用于不同種類的情況。
過渡用于在給定時間內從一個動畫狀態平滑過渡到另一動畫狀態。過渡作為動畫狀態機的一部分指定。如果過渡很快,從一個運動到完全不同運動的過渡通常沒有問題。
混合樹允許通過不同程度合并多個動畫來使動畫平滑混合。每個運動對最終效果的影響由一個混合參數控制,該參數只是與 Animator Controller 相關聯的數字動畫參數之一。為了使混合后的運動合理,要混合的運動必須具有相似的性質和時機。混合樹是動畫狀態機中的一種特殊狀態類型。
????????例如,類似運動可能是各種行走和奔跑動畫。為了使混合取得良好效果,剪輯中的動作必須在標準化時間內的相同點進行。例如,可將行走和奔跑動畫對齊,使得腳與地面的接觸時刻發生在標準化時間內的相同點(例如,左腳接觸點為 0.0,右腳接觸點為 0.5)。由于使用標準化時間,因此剪輯長度不同并不要緊。
????????總之可以理解為相比于之前的動畫過渡,混合樹可以實現更加順滑、更加自由的動畫過渡。
2.5.1 創建混合樹
-
右鍵單擊 Animator Controller 窗口上的空白區域。
-
從顯示的上下文菜單中,選擇 Create State > From New Blend Tree。
-
雙擊混合樹 (Blend Tree) 以進入混合樹視圖 (Blend Tree Graph)。
2.5.2 混合樹參數面板
????????點擊Blend Tree,Inspector中顯示內容如下:
Blend Type(混合樹類型)
-
1D:1D模式,只有一個參數控制。
-
2D Simple Directional:2D模式,有兩個參數控制。適合不同方向的動畫混合,比如向前、后、左、右,若是前走和前跑就不合適了。在(0,0)位置可以選擇放入一個Motion(下面有解釋),比如待機狀態。PS:在權重圖上的具體感覺是,過渡只有在靠近閾值時才會發生快速的動畫過渡,遠離閾值時,在較大閾值范圍內都是混合動狀態。
-
2D Freeform Directional:2D模式,有兩個參數控制。適合方向不同的動畫混合,也適合同方向的混合。在(0,0)位置應該有一個Motion,比如待機。PS:在權重圖上看,若兩個Motion在權重圖上是相對于原點直線,則在以直線切換經過原點并且原點(0,0)處無動作時,狀態會發生較為僵硬快速的變化,看起來沒有過渡而是直接切換了動作,所以需要在原點處加上一個Motion作為過渡,通常設置為待機動作。
-
2D Freeform Cartesian:2D模式,有兩個參數控制。適合兩個參數不是全都是表示方向時的動畫混合。意思就是我們是2D嘛,所以有兩個參數嘛,通常這兩個參數分別表示前后方向和左右方向,現在就是不全表示方向,保留前后方向參數,另外一個參數改成別的,比如角速度,來實現往前跑轉彎效果,這時一個參數是方向,另一個是角速度,滿足“兩個參數不是全都是表示方向”,此時便適合用這個類型。
-
Direct:直接混合。可以直接控制每個節點的權重,之前的都是權重分配都會在靠近一個Motion時,削減其他Motion的權重,而這個則是無視這個情況,比如兩個Motion都是設置為權重1(此模式權重范圍0-1),那么就是兩個Motion權重都是1而不是各自0.5。適合于面部表情之類的。
PS:這幾個2D概念說這么多還是模糊,實際還是要在具體使用中多嘗試看看區別才行,這樣才能更好的理解。
Parameter(參數)
????????即Animator面板中創建的參數。可選擇創建參數中的Float類型參數。若無Float類型參數,則在混合樹被創建時自動創建一個Float類型的Blend參數。
Motion(動作)
????????可以是動畫或是子級混合樹。點擊加減號操作,或是右鍵混合樹視圖中的Blend Tree操作。
Blend Type詳細說明
Blend Type 1D:
????????在我加入動作后,窗口內容會發生變化。
????????首先看動畫列表,由左往右是動畫、閾值、動畫速度(時間縮放)、動畫是否鏡像。這里特別說下閾值,當Parameter的值為對應Motion的閾值時,此為Motion運行100%時候的值,因為是混合樹,所以Motion的運行大多數都是混合的,所以運行時不同Motion占有不同的比例權重,100%可以理解為完全在運行當前Motion,其他Motion沒有與其混合運行。然后上方會顯示一個藍色的圖像,y軸是權重占比,x軸是Parameter值(范圍是閾值的范圍),圖中每個三角都是一個Motion,表示所有Motion在不同Parameter值下的權重占比。
????????同時下方也出現了新參數。Automate Thresholds是自動閾值的意思,勾選后我們無法自己設置閾值,其會根據動畫的加入自動調整。當我將其去掉勾選后便可以自己調整了,且會出現新的參數。
Compute Thresholds,計算閾值,即提供的幾種閾值計算方法,選擇后會自動應用到閾值上。
Adjust Time Scale,調整時間縮放,也是提供的幾種時間縮放方法,可選擇使用。 可以看一下混合動畫的效果:
Blend Type 2D:
????????以2D Freeform Directional為例。2D是需要兩個Float類型參數的,這里設置為Blend1和Blend2,并將加入Walk和Run動畫Motion,之后權重圖如下:
首先權重圖是一個x、y軸組成的二維坐標系。圖中兩個藍點是Motion 100%權重位,紅點是Blend1和Blend2組成點(x,y),Blend1表x值,Blend2表y值。當紅點靠近藍點時,藍點Motion的混合權重就會增大。下方Motion列表中增加了PosX、PosY,其用于設置Motion藍點在權重圖中的位置,x、y軸的值沒有范圍限制,可任意設置。
????????這里再多增加幾個Motion,加入待機、前走、后退、左走、右走、前跑、后退跑、左跑、右跑。此時權重圖如下:
然后可以看下混合效果:
2.6 子動畫狀態機
????????子狀態機和狀態機是基本一樣的,只是套娃關系,但當然還是有一些小區別的。
2.6.1 創建子狀態機
????????在狀態機內鼠標右鍵,Create Sub-State Machine。
2.6.2 子狀態機與其他狀態機的聯系
????????左鍵雙擊創建的子狀態機后即可而進入子狀態機內,如下:
基本一樣,特別注意(Up)Base Layer,其表示當前狀態機的上層狀態機(所有上層)。我先加入一個狀態,再將加入狀態連接到(Up)Base Layer,如下:
當我連接后出現了兩種選項,第一個是其他狀態,即上層中的所有狀態都會給你列出來,包括上層的子狀態機的,選擇狀態就會在上層當前子狀態機拉一條線連接到選擇的狀態;第二個是狀態機,若是選擇狀態機,則默認是從所選狀態機的Entry來切換狀態。
2.6.3 Exit狀態
????????若是最終連接到Exit來退出,那么會回到上一層,若在上層子狀態機有連線到其他地方且滿足條件,則走此路線,若不滿足或無連線則從Entry進入。
????????PS:但我用起來感覺有時候改變參數狀態機卻沒生效,這種情況發生在使用狀態機去連接的情況,這時候線是灰色的,若是從子狀態機內直接連接外面的狀態,則是白色的線,就不會出現這種情況。另外,Entry是連接到默認狀態的,前面說了不滿足條件的話會從Entry進入然后到默認狀態,但若狀態機本身有條線連接到默認狀態,那么無論次連線條件是否滿足,都會走這條線,就結果來看沒有變化,都是執行默認狀態。
2.7 重寫動畫控制器
????????若我們已經實現了一套動畫控制器,這時候我們想在原先動畫控制器的基礎上替換一套動畫,即僅僅替換動畫,而其他的所有設置都不改變,比如不同職業間的動作狀態過渡是相同的設計,但只是動畫不同,那我們就只需替換一套動畫即可。此時便可以使用“重寫動畫控制器”。創建如下:
創建后,選中動畫控制器,Inspector面板如下:
Controller即要重寫的控制器,把之前的控制器拖入:
可以替換的動畫就會被顯示到下方,只需要將新動畫拖入對應位置即可,若沒有拖入新動畫則使用原控制器的動畫。
????????之后只需要將重寫動畫控制器替換角色Animator組件上的原控制器,即可使用新一套動畫了。
3 動畫事件
????????動畫剪輯的事件。我們可以在動畫剪輯中添加事件,進而可以在動畫的特定位置執行處理函數。比如在動作做到一半時觸發特效什么的。
3.1 添加動畫事件
????????需要在Animation窗口中添加動畫事件,如圖:
添加后就會出現一個小圖標表示這里有事件,點擊可在Inspector面板中看到Animation Event的參數設置,這里可以選擇處理函數。(注意這里我把事件添加到了動畫大概中間的位置)
那么如何選擇我們自定義的方法呢?
3.2 提供處理方法
????????首先看這個動畫剪輯處于哪個游戲對象身上,這里我添加的動畫剪輯是在Cube身上,具體關系是:Cube對象→Animator組件→Cube動畫控制器→動畫剪輯。如圖:
Cube動畫控制器中:
????????那么在找到是屬于哪個游戲對象后,那么只需要在掛載在此對象身上的腳本中添加公共方法即可,這些公共方法是可以在剛才的Inspector面板中識別并選擇的。這里我添加了一個Cube.cs腳本掛載到Cube對象身上,代碼如下:
using UnityEngine;public class Cube : MonoBehaviour
{public void AnimationEventTest(){Debug.Log("觸發動畫事件!");}
}
之后我們再去點擊Animation窗口中的事件標志,在Inspector面板中的Animation Event的參數設置中發現此時可以選擇代碼中的函數。
選擇函數后運行程序,會發現在動畫播放到大概中間的位置時,控制臺將輸出內容。
3.3 演示
3.4 更詳細的Animation Event參數設置
3.4.1 參數設置
????????剛剛我們看到Animation Event參數設置中只有一個方法參數,但是當我們選中動畫剪輯的原始文件,再次點擊事件標志時,將看到更相機的Animation Event參數設置,如下:
可以看到可設置的參數有5個,第一個是Function,表示選擇的處理函數,后面多出來的四個參數則是提供給處理函數使用的,我們可以先在這里設置好參數值,之后在處理函數中可使用這些值。
-
Function:處理方法。
-
Float:float類型參數。
-
Int:int類型參數。
-
String:string類型參數。
-
Object:Object類型參數(注意O是大寫)。Object作為祖先類意味著這里可以傳遞的對象的類型很自由,在函數中使用時需要注意把類型轉換為傳遞對象的原始類型。比如傳遞的對象是A類型,那么在函數中就需要轉為A類型。
PS:點擊游戲對象再點擊事件標識,就可以看到簡化的Animation Event參數設置。若處理函數傳遞了“參數”,則簡化后的參數設置中也會顯示“參數”。
3.4.2 函數傳參
????????將參數傳遞給函數,進而提供給函數使用。傳給函數的參數只能有一個。傳參的方式可以分為兩種:
-
傳遞單個參數
-
傳遞所有參數
具體使用哪種,是在定義處理函數時決定的。
傳遞單個參數的例子:
using UnityEngine;public class Cube : MonoBehaviour
{//只能傳遞一個參數//傳遞int類型參數,變量名隨意,也可以換成其他設置類型public void AnimationEventTest(int num){Debug.Log("觸發動畫事件!" + num);}
}
傳遞所有參數的例子:
using UnityEngine;public class Cube : MonoBehaviour
{//只能傳遞一個參數//傳遞一個AnimationEvent類型,變量名隨意,內部包含所有參數public void AnimationEventTest(AnimationEvent allPamams){Debug.Log("float類型參數:" + allPamams.floatParameter);Debug.Log("int類型參數:" + allPamams.intParameter);Debug.Log("string類型參數:" + allPamams.stringParameter);Debug.Log("Object類型參數:" + allPamams.objectReferenceParameter);//真實使用場景別忘了根據需要轉換類型Debug.Log("處理函數名:" + allPamams.functionName);}
}