摘要:【長文預(yù)警唉侄,建議先收藏】有了模型和多個動畫以后咒吐,在Unity中如何控制它們的播放和切換呢?本文帶你一站式解析Unity的Animator模塊属划。
洪流學堂恬叹,讓你快人幾步。你好同眯,我是跟著大智學Unity的萌新绽昼,我叫小新,這幾周一起來復(yu)習(xi)動畫系統(tǒng)须蜗。
大智:“小新绪励,還記得Unity的動畫來源有哪些么?”
小新:“有Unity中制作和外部導入兩種唠粥,哦對疏魏!還可以用代碼寫動畫,不過我不會晤愧,嘿嘿”
大智:“沒錯大莫,前兩天我們學習的其實主要是Animation Clip的內(nèi)容,也就是一個物體對應(yīng)的一段動畫官份,是整個動畫系統(tǒng)的基本元素只厘。今天我們要著重學習一下Animator烙丛。如果把Animation Clip比作是一段視頻的話,那么Animator就是一個視頻播放器羔味,用來控制多段視頻的播放河咽、切換等等「吃”
Animator組件
想要在一個物體上播放動畫忘蟹,需要在這個物體上添加Animator組件。
Animator中有一個很重要的屬性是Controller搁凸,這個屬性引用了一種叫Animator Controller的資源媚值,這種資源以文件的形式存儲在工程中,文件內(nèi)存儲了動畫的各種狀態(tài)以及狀態(tài)之間的切換規(guī)則护糖。本文后半部分會細講褥芒。
Avatar 設(shè)置使用的骨骼節(jié)點映射。
Apply Root Motion 應(yīng)用根節(jié)點運動嫡良。如果不啟用锰扶,動畫播放時根節(jié)點會保持在原地,需要通過腳本控制物體的移動寝受。如果啟用少辣,如果動畫中有運動,動畫中的運動會換算到根節(jié)點中羡蛾,根節(jié)點會發(fā)生運動。(通常用于人物/動物的運動動畫)
Update Mode 設(shè)置Animator更新的時機以及timescale的設(shè)置锨亏。
- Normal Animator按正常的方式更新(隨著Update調(diào)用更新痴怨,timescale減小時,動畫播放也會減慢器予,timescale的具體含義和用法后續(xù)會詳解)
- Animate Physics Animator會按照物理系統(tǒng)的頻率更新(根據(jù)FixedUpdate調(diào)用更新浪藻,后續(xù)會詳解),適用于物理交互乾翔,例如角色加上了物理屬性可以推動周圍的其他物體爱葵。
- Unscaled Time 根據(jù)Update調(diào)用更新,無視timescale反浓。一般用于UI界面萌丈,當你使用timescale暫停游戲時,界面保持正常動畫雷则。
Culling Mode 裁剪模式
- Always Animate 動畫一直運行辆雾,即使物體在屏幕外被裁剪掉并沒有渲染
- Cull Update Transforms 當物體不可見時,禁用Retarget月劈、IK度迂、Transforms的更新(后續(xù)動畫進階模塊會細講)
- Cull Completely 當物體不可見時藤乙,完全禁用動畫
Animator Controller
Animator Controller是Animator組件必須的資源,這種資源以文件的形式存儲在工程中惭墓,文件內(nèi)存儲了動畫的各種狀態(tài)以及狀態(tài)之間的切換規(guī)則坛梁。
通常一個物體上有不止一段動畫,使用Animator Controller可以很容易地管理各段動畫以及動畫之間的切換腊凶。比如角色身上有走划咐、跑、跳吭狡、蹲的動畫尖殃,使用Animator Controller可以很容易管理它們。不過划煮,即使只有一段動畫送丰,仍然需要給動畫物體添加Animator組件才能播放動畫。
大智之前講過可以使用PlayableAPI繞過Animator Controller來播放動畫弛秋,感興趣的話可以去看一下
Animator Controller中使用了一種叫State Machine(狀態(tài)機)的技術(shù)來管理狀態(tài)以及狀態(tài)之間的切換器躏。
StateMachine 狀態(tài)機
狀態(tài)機由State(狀態(tài))和Transition(轉(zhuǎn)換)組成。State代表一個狀態(tài)蟹略,在Animator Controller中一個State可以包含一段動畫登失、一個子狀態(tài)機或一個混合樹(后面會細講)。Transition用來設(shè)置狀態(tài)之間的切換條件挖炬,一般會有一個或多個條件揽浙,用于從一個狀態(tài)切換到另一個狀態(tài)。
在Animator窗口中意敛,可以可視化看到State以及Transition馅巷。
創(chuàng)建Animator Controller
創(chuàng)建Animator Controller資源有如下幾種方式:
- 在Unity中創(chuàng)建Animation Clip時,如果選中的GameObject上沒有Animator組件草姻,會自動添加Animator組件并在工程中創(chuàng)建一個Animator Controller文件(和Animation Clip文件同目錄)钓猬。
- 將任意Animation Clip拖到一個物體上時,如果拖到的物體上沒有Animator組件撩独,會自動添加Animator組件并在工程中創(chuàng)建一個Animator Controller文件(和Animation Clip文件同目錄)敞曹。
- 可以在Project窗口中手動創(chuàng)建Animator Controller文件,如下圖所示:
編輯Animator Controller
雙擊Animator Controller文件综膀,可以打開Animator窗口澳迫,編輯該文件。
今天我們先簡單學習一下如何將導入的動畫播放出來剧劝,后續(xù)的動畫進階模塊會更詳細講解Animator Controller中的高級功能纲刀。
在Project窗口中直接創(chuàng)建Animator Controller時,其中是不包含任何動畫的。如下圖所示:
圖中包含三個節(jié)點:
Entry 入口示绊。動畫狀態(tài)機會從這個節(jié)點開始锭部,根據(jù)Transition進入一個默認State。
Any State 任意狀態(tài)面褐。用于從任意狀態(tài)轉(zhuǎn)換到特定狀態(tài)拌禾。比如射擊類游戲中,如果被子彈打中后展哭,不管當前處于什么狀態(tài)湃窍,都會倒地死亡。
Exit 退出狀態(tài)機匪傍。一般用于嵌套的狀態(tài)機的退出(后面動畫進階模塊會講)您市。
添加狀態(tài)
可以在空白處右鍵添加Empty State,也可以將Animation Clip文件拖到Animator窗口中添加一個State役衡。
如果當前在Project窗口選中了一個Animation Clip茵休,也可以通過上圖的From Selected Clip創(chuàng)建一個State,不過還是直接將Clip拖到Animator中創(chuàng)建State更簡單榕莺,如下圖所示。
第一個創(chuàng)建的State默認是橘黃色的棵介,代表是默認狀態(tài)钉鸯。有一條黃色的箭頭從Entry指向橘黃色的State。Animator組件會在一開始播放New State邮辽,如果New State中有動畫唠雕,也會播放對應(yīng)的動畫。
這時候如果你Play這個場景的話吨述,設(shè)個物體就會播放默認State的動畫岩睁。
State設(shè)置
每個State可以包含一段Animation Clip,處于該State時Animator組件所在的物體會播放該動畫锐极。選中一個State時,在Inspector中可以看到如下內(nèi)容:
Motion 可以設(shè)置一個Animation Clip芳肌,如果是從Animation Clip創(chuàng)建的動畫灵再,這里應(yīng)該已經(jīng)有動畫了,你也可以從工程中選擇動畫亿笤。
Speed 動畫的播放速度
Multiplier 乘數(shù)翎迁,可以使用一個參數(shù)來控制動畫的播放速度,動畫最終的播放速度會是Speed * Multiplier净薛。后面會講解Animator的參數(shù)以及如何在代碼中控制參數(shù)汪榔。
Normalized Time 單位化時間,范圍是0-1肃拜,需要使用參數(shù)控制痴腌。
Mirror 鏡像動畫雌团。也可以使用一個參數(shù)控制。
Cycle Offset 循環(huán)偏移量士聪〗踉可以用來同步循環(huán)的動畫。偏移量使用的是單位化時間剥悟,范圍是0-1灵寺。也可以使用參數(shù)來控制。
Foot IK 只用于人形動畫区岗。角色的腳是否使用反向動力學略板。
Write Defaults 是否初始化該State沒有用到的參數(shù)為默認值。
Transitions 該狀態(tài)參與的狀態(tài)轉(zhuǎn)換慈缔。下面會細講叮称。
Parameters 參數(shù)
上面我們提到了參數(shù)的概念,那么參數(shù)是什么呢胀糜?
Animator Controller中的參數(shù)可以作為控制transition切換的條件颅拦,也可以控制上面可以參數(shù)化的屬性比如State中的幾個屬性。
Animator Controller的參數(shù)可以通過代碼進行控制教藻,進而控制整個Animator狀態(tài)機的運轉(zhuǎn)距帅。
參數(shù)共有4種類型:
- Int 整數(shù)類型
- Float 浮點數(shù)(小數(shù))類型
- Bool true或false(真或者假,用于邏輯判斷)括堤,界面上顯示為復選框
- Trigger 觸發(fā)器碌秸,與Bool有點類似,但是transition在使用這個參數(shù)后會被自動設(shè)置為false狀態(tài)悄窃。界面上顯示為一個圓形按鈕讥电。
Transition
Transition代表狀態(tài)之間的切換條件,一般會有一個或多個條件轧抗,用于從一個狀態(tài)切換到另一個狀態(tài)恩敌。
添加Transition
在一個State上右鍵,在彈出菜單中選擇Make Transition横媚,可以創(chuàng)建一個到其他State的Transition纠炮。
點擊代表Transition的箭頭,可以在Inspector上看到這條Transition的具體情況灯蝴。選中Transition的源State(從哪個State出發(fā))恢口,也可以在State的Inspector中看到這條Transition的具體信息。
Transitions 顯示當前選中的Transition穷躁。后面有兩個復選框包括Solo和Mute耕肩。
- Solo 如果兩個State之間有多條Transition,勾選這個選項后,只有選中Solo的Transition生效猿诸。其他Transition會被禁用婚被。
- Mute 勾選這個選項后两芳,該條Transition會被禁用摔寨。如果同時選中了Solo和Mute,Mute會優(yōu)先生效怖辆。
Name Field 名稱框是复。如上圖所示,可以給Transition命名,用于區(qū)分兩個State之間的多個Transition時非常有用。
Has Exit Time 是否有退出時間條件凳鬓。退出時間是一種特殊的transition條件,它沒有依賴參數(shù)(下面會講)季惩,而是根據(jù)設(shè)置的退出時間點作為條件進行狀態(tài)轉(zhuǎn)換。
Settings transition的一些參數(shù)設(shè)置腻格。
-
Exit Time 如果勾選了Has Exit Time画拾,該參數(shù)是可以設(shè)置的,設(shè)置動畫退出的單位化時間菜职。例如設(shè)置為0.75青抛,代表動畫播放到75%時為true,如果沒有其他條件酬核,會直接切換到下一個State蜜另。
如果exit time小于1,那么state每次循環(huán)到對應(yīng)位置的時候(不管動畫是否設(shè)置為循環(huán)嫡意,state總是循環(huán)的)举瑰,該條件都會為true。比如第一次播放到75%蔬螟,第二次播放到75%……時退出條件都會為true此迅。
如果exit time大于1,該條件只會檢測一次旧巾。比如exit time為3.5耸序,state的動畫會在循環(huán)3次后,在播放到第4次的50%時為true菠齿。
Fixed Duration 勾選時佑吝,下方Transition Duration參數(shù)的單位是秒坐昙,不勾選時绳匀,參數(shù)會作為一個百分比。
Transition Duration transition的過渡時間。兩個狀態(tài)在轉(zhuǎn)換時疾棵,一般不會瞬間從一個狀態(tài)轉(zhuǎn)換到另一個狀態(tài)戈钢,而是會經(jīng)過平滑混合,這個屬性就是設(shè)置了平滑混合的時間是尔⊙沉耍可以從下圖的兩個藍色箭頭看出轉(zhuǎn)換的時間。
- Transition Offset 目標狀態(tài)開始播放的時間偏移拟枚。比如設(shè)置為0.5薪铜,則轉(zhuǎn)換到下一個State時,會從50%的位置開始播放恩溅。
- Interruption Source和Ordered Interruption 這兩個參數(shù)可以用來控制transition的打斷。下面會進行詳解脚乡。
Transition圖
上面的參數(shù)不僅可以手動修改數(shù)值蜒滩,也可以通過Transition圖預(yù)覽、修改奶稠。
Conditions 條件
一個Transition可以有一個條件俯艰,也可以有多個條件,甚至沒有條件锌订。
如果Conditions中沒有條件竹握,但是勾選了Has exit time,那么exit time會被作為state退出的條件瀑志,到達exit time時涩搓,會切換到下一個state。
如果有一個或多個條件劈猪,需要同時滿足這些條件才能切換下一個state昧甘。
一個條件可以是:
- 相等/不相等判斷,一個參數(shù)等于/不等于一個常量時為true(int战得,float充边,bool類型參數(shù))
- 比較判斷,一個參數(shù)與一個常量的比較結(jié)果(int常侦,float類型參數(shù))
- 觸發(fā)器浇冰,觸發(fā)器激活時為true
如果Has Exit Time勾選了,并且transition還有一個或多個條件聋亡,那么transition需要同時滿足到達exit time同時條件全為true肘习,才會切換到下一個state。
一個transition至少要有一個條件(Has Exit Time可以作為一個條件)坡倔,否則transition會被忽略漂佩。
【選讀】Transition Interruption
之前我們提到了Interruption Source和Ordered Interruption 這兩個參數(shù)可以用來控制transition的打斷脖含。那么究竟什么是transition打斷呢?
一般情況下投蝉,動畫系統(tǒng)的transition是不能打斷的:一旦transition開始從一個state切換到另一個state养葵,沒有打斷的方法。就像乘坐跨大西洋航班的乘客一樣瘩缆,你舒適地坐在座位上关拒,直到到達目的地,無法改變主意庸娱。對于大多數(shù)用戶來說着绊,這很好。
但是如果你需要對transition進行更多控制熟尉,可以通過多種方式配置動畫系統(tǒng)來滿足需求靶擦。如果你對目前的目的地不滿意棚放,你可以跳進飛行員的座位,在飛行途中改變計劃。這能帶來更靈活的動畫控制,但也很有可能迷失在復雜的打斷中犬辰。
我們通過幾個例子來深入探索一下打斷诫欠。從一個相當簡單的狀態(tài)機開始,這個狀態(tài)機具有四個狀態(tài),標記為A到D,并且使用trigger作為每個transition的條件法精。
默認情況下帮碰,當A到B的切換觸發(fā)后,狀態(tài)機開始切換到B,在切換到B之前無法被改變。但是猴抹,如果將A->B的transition的interruption source屬性從None切換到Current State,A到B的切換就可以被A上的一些觸發(fā)器中斷。
為什么只有一些呢骡湖?因為Ordered Interruption屬性默認也會被勾選浦夷。這意味著只有優(yōu)先級大于當前的transition才能打斷肾档。選中State A,在Inspector中查看舵变,我們看到A -> C的優(yōu)先級高于 A -> B,那也意味著只有A -> C能打斷A -> B的轉(zhuǎn)換瘦穆。
如果我們激活A(yù)->B的trigger纪隙,然后立馬激活A(yù)->D的trigger,A到B的transition不會被打斷扛或。但是绵咱,如果我們激活A(yù)->B的trigger,然后立馬激活A(yù)->C的trigger熙兔,A到B的transition會被打斷悲伶,轉(zhuǎn)而切換到C艾恼。
在動畫系統(tǒng)內(nèi)部,會記錄下被打斷時的動畫的狀態(tài)麸锉,然后從打斷的狀態(tài)混合到新的目標動畫钠绍。
如果不勾選Ordered Interruption屬性,會發(fā)生什么情況呢花沉?A->C 和 A->D 都能打斷 A -> B 的transition了柳爽。但是,如果在同一幀激活了A->C和A->D的trigger主穗,A->C仍然會優(yōu)先激活因為A->C的優(yōu)先級更高。
如果將A -> B的interruption source屬性改為Next State毙芜,也就是下一個狀態(tài)忽媒。A->C 和 A->D就不能打斷A -> B了。如果我們激活A(yù)->B的trigger腋粥,然后立馬激活B->D的trigger晦雨,A到B的transition會被打斷,轉(zhuǎn)而切換到D隘冲。
B上的Transition的順序也有影響闹瞧。但是這時候Ordered Interruption屬性就無法勾選了(因為A -> B是在State A上不在State B上,不參與B的排序)展辞。B上transition的順序會決定同時觸發(fā)時奥邮,會使用哪一個transition。例如下圖的排序罗珍,如果B->D 和B->C在同一幀被觸發(fā)洽腺,B->D的transition會被執(zhí)行。
如果想完整控制覆旱,我們可以設(shè)置interruption source屬性為Current State Then Next State或Next State Then Current State蘸朋。設(shè)置為這兩個值時,State A和State B上的transition都會被考慮在內(nèi)扣唱。例如設(shè)置如下藕坯,選中了Current State Then Next State:
如果A到B切換時,同時激活的A->C, A->D, B->C和B->D噪沙,會發(fā)生什么情況炼彪?
如果選中了Ordered Interruption,那么首先可以忽略A->D(因為比A->B)的優(yōu)先級低正歼。然后先考慮Current State A霹购,那么A->C會勝出,甚至不用考慮Next State B了朋腋。
如果同樣的配置齐疙,只激活了B->C 和 B->D膜楷,那么B->D會勝出,因為B->D的優(yōu)先級比B->C更高贞奋。
小結(jié)
上面我們只使用了A->B一種情況作為例子進行了講解赌厅,其他的中斷都是類似的,只需要根據(jù)他們自身的規(guī)則即可轿塔。
有一點很重要需要記住的是:不管打斷發(fā)生了幾次特愿,只要transition沒有完成,source state會一直不會變勾缭。比如A->B被B->C打斷揍障,又被C->D打斷,transition未完成前source state會一直是A俩由。Animator.GetCurrentAnimatorStateInfo()也會返回State A毒嫡。
簡而言之,transition中斷功能很強大幻梯,并提供了很大的靈活性兜畸,但會變得非常混亂碘梢。因此咬摇,合理地使用transition中斷,而且一定要在編輯器中多進行測試煞躬。
總結(jié)
今天講了Animator組件肛鹏,希望你能記住一下幾點:
- 如果把Animation Clip比作是一段視頻的話,那么Animator就是一個視頻播放器恩沛,用來控制多段視頻的播放龄坪、切換等等。
- Animator Controller就是一個劇本复唤,用來指導視頻播放器如何播放多段視頻健田。
今日思考題
大智:“導入Standard Assets中的Character包,看看里面的Animator Controller是如何設(shè)置的佛纫〖司郑”
小新:“好嘞~”
大智:“收獲別忘了分享出來!別忘了點擊右下角請好友看免費分享給你的朋友呈宇,也許能夠幫到他好爬。”
擴展閱讀
- Unity動畫系統(tǒng)詳解1:在Unity中如何制作動畫甥啄?
- Unity動畫系統(tǒng)詳解2:如何導入使用外部的動畫存炮?
- 【建議收藏】找不到免費的角色動畫?來試試mixamo
- 2018.1之后Standard Assets如何安裝?
- 5分鐘制作過場動畫
- 5分鐘入門Cinemachine智能相機系統(tǒng)
- Unity編輯器錄屏神器:Unity Recorder
【擴展學習】在洪流學堂公眾號回復
動畫
可以閱讀本系列所有文章穆桂,更有視頻教程等著你宫盔!
呼~ 今天小新絮絮叨叨的真是夠夠的了。沒講清楚的地方歡迎評論享完,咱們一起探索灼芭。
我是大智(微信:zhz11235),你的技術(shù)探路者般又,下次見彼绷!
別走!點贊茴迁,收藏哦寄悯!
好,你可以走了堕义。