摘要:“Animator中有一個功能,用來解決多個動畫之間的混合,經(jīng)常用于移動動畫之間的混合,這個功能叫做BlendTree,混合樹。”
大話Unity,讓你快人幾步。你好,我是跟著大智學(xué)Unity的萌新,我叫小新,這幾周一起來復(fù)(yu)習(xí)(xi)動畫系統(tǒng)。
“智哥,我用Animator做了一個人物移動的狀態(tài)機,怎么看怎么不順眼,這也太復(fù)雜了,你來看看?”

“喲,這不是挺規(guī)整的嘛,我看起來挺順眼的,哈哈哈”
“去去去,我這光一個走路的就得搞這么復(fù)雜,而且還沒法斜著跑,我這做一個動畫,這得多少個狀態(tài)啊”
“emmm,我這有一個秒招,不知道你想學(xué)不想學(xué)?”
“那當(dāng)然想學(xué)了,看我每天學(xué)習(xí)的熱情多么高漲”
“那你先帶我去把晚飯解決了”
“哎呀,咱們點個外賣,我已經(jīng)等不及了,吃飯這都不重要”
“那也成,給我來個10斤的龍蝦,點好了再來找我”
小新花了30秒搞定外賣,“快快快,開始上課!”
“看你小子猴急的,以后能成大器,嘿嘿”
BlendTree 混合樹
“Animator中有一個功能,用來解決多個動畫之間的混合,經(jīng)常用于移動動畫之間的混合,這個功能叫做BlendTree,混合樹。”
“混合樹和Transition中的混合有啥區(qū)別呢?”
“混合樹和Transition中的混合不同,Transition中的混合只是在兩個State轉(zhuǎn)換時,在給定的時間內(nèi)進行混合,避免動畫切換過于突兀。而混合樹中的混合,是時時刻刻進行不同程度的混合。比如你的角色有站立、走、跑三個動作,走路的速度是2m/s,跑的速度是5m/s,那你想讓角色的速度是3m/s,這時候怎么辦?這時候用混合樹就能很簡單地解決?!?/p>
“聽起來很厲害,那你用我的這個移動的例子給我講講怎么搞唄?”
“不要著急,這時候你應(yīng)該先去看看混合樹的文檔,自己試試,看看會遇到什么問題”
“好,那我先去看看文檔”
“嗯,對了,我的大龍蝦呢?”
“嘿嘿,大龍蝦沒有,不過給你點了個龍蝦飯,看我夠意思吧”
“哎,湊活吧,以后再讓我教你可就難啦”
小新回到自己的房間,開始學(xué)習(xí)混合樹的文檔,并且記了筆記。
創(chuàng)建混合樹
在Animator窗口的空白處右鍵,Create State > From New Blend Tree,雙擊這個節(jié)點可以進入混合樹圖。

混合樹有3種類型,在右邊的Blend Type中可以設(shè)置。分別為:
- 1D
- 2D
- Direct
1D混合
1D混合是根據(jù)一個參數(shù)進行動畫混合。
1、首先要設(shè)置用于混合的參數(shù),也就是從Animator的Parameters中的選擇一個參數(shù)。
2、添加動畫:可以點擊小加號按鈕,或者在Blend Tree節(jié)點上右鍵Add Motion。點擊后會在Motion列表中添加一個條目,可以將Animation Clip拖進來。

添加完動畫,整個混合的樣子:

最上面的圖顯示了參數(shù)對每個動畫的影響。每個動畫顯示為一個藍色的三角形。如果點擊這個三角形,會在下面的動畫列表中高亮一下。每個三角形的頂角位置定義了參數(shù)在該位置時,會完全使用這個動畫,這個值也叫做該動畫的閾值(Threshold)。比如上圖中的run動畫,閾值是0.5,在混合圖的中心位置。
圖中的紅線代表了參數(shù)的數(shù)值,主要是用來預(yù)覽調(diào)試。可以拖動紅線,在下面預(yù)覽窗口觀察動畫式如何混合的。

參數(shù)范圍

上圖中,左右兩個數(shù)字代表了參數(shù)的范圍。點擊數(shù)字可以變成輸入框修改,也可以在數(shù)字上拖拽調(diào)節(jié)。修改時會影響到第一個動畫和最后一個動畫的閾值。
Threshold 閾值
修改動畫對應(yīng)的閾值可以直接拖拽對應(yīng)的藍色三角形。如果沒有勾選Automate Threshold(自動計算閾值),也可以在閾值編輯框中直接輸入數(shù)值。選中Automate Threshold(自動計算閾值)時,閾值會自動在最小值和最大值之間自動平均分布。
下面有一個Compute Thresholds下拉框,使用這個下拉框,可以根據(jù)動畫中的數(shù)據(jù),自動計算閾值。數(shù)據(jù)包括:speed(速度),velocity x、y、z(xyz三個軸分別的速度),angular speed(轉(zhuǎn)動速度,單位是角度或弧度)。這些數(shù)據(jù)如何知道呢?
比如:走路動畫的速度是1.5m/s,跑的速度是4m/s,如果選擇Compute Thresholds中的Speed,walk動畫的閾值會被設(shè)置為1.5,run動畫的閾值會被設(shè)置為4。
Time Scale

通過動畫速度這一列(圖標(biāo)是一個表)可以調(diào)節(jié)動畫的播放速度,比如你想讓跑步的動畫播放速度變?yōu)樵瓉淼?倍,可以設(shè)置為2。
**Adjust Time Scale > Homogeneous Speed ** 可以將動畫的速度調(diào)整對應(yīng)到參數(shù)的最小值和最大值,但是保持動畫的初始相對速度。
這句話看得我欲生欲死,得問問大智是什么意思
按鈕可以將動畫的播放速度調(diào)整到動畫列表中所有動畫速度的平均值。
Mirroring 鏡像

上面復(fù)選框可以左右鏡像一個humanoid類型的動畫Clip。這個功能可以使用同一個動畫創(chuàng)建出來兩個方向的動畫,可以節(jié)省一倍的存儲空間和內(nèi)存。
比如一個向左走的動畫,通過鏡像可以創(chuàng)建出一個向右走的動畫。
難點解析
這時候門鈴響了,“先生,您的龍蝦飯到了。祝您用餐愉快,給個5星好評唄~”
“大智,吃飯前問你兩個問題唄”
“不行,我得看看這個龍蝦飯到底怎么樣”
說著大智以迅雷不及掩耳之速拆開了包裝,吃了幾口。
“嗯,還不錯,心情大好,來問吧!”
“我選的,能不好吃嘛!”
“第一個問題:自動計算Threshold的時候,那些動畫的速度啊,旋轉(zhuǎn)速度怎么知道???”
“選中一個Animation Clip,你可以看到這些數(shù)據(jù),比如這個:”

“第一行是這個動畫在xyz軸上的速度,第二行是旋轉(zhuǎn)速度?!?/p>
“原來在這,這里我還沒仔細看過呢”
“以后會用到的”
“第二個問題:**Adjust Time Scale > Homogeneous Speed **這個到底是干嘛的,怎么我看了半天都沒看明白文檔中的含義?”
“我記得文檔中的解釋有一些難理解,其實這個按鈕的作用就是:先將所有動畫的平均速度算出來,然后通過調(diào)節(jié)動畫的speed讓所有動畫的速度都一致。”
“啊?真的么?我怎么看文檔跟這個一點聯(lián)系都沒有呢?”
“不信你去試試,看看是不是我說的這樣”
“OK,你趕緊吃飯吧,我要繼續(xù)去看了,2D混合樹還沒看呢”
小新回到房間繼續(xù)學(xué)習(xí)2D混合樹,下面是他做的學(xué)習(xí)筆記。
2D混合樹
2D混合樹可以根據(jù)2個參數(shù)進行動畫混合。

2D混合樹有三個選項,分別是:

2D Simple Directional(2D簡單方向):當(dāng)你的運動代表不同的方向,如“向前走”,“向后走”,“向左走”,“向右走”,或“向上瞄準(zhǔn)”,“向下瞄準(zhǔn)”,“左瞄“和”右瞄“。當(dāng)然了,可以在(0,0)處包含一個默認(rèn)動作類似“空閑站立”或“直線瞄準(zhǔn)”。與1D混合樹不同的是,2D Simple Directional不是在同一個方向上的多個動作,比如“走”和“跑”。
2D Freeform Directional(2D自由方向):動畫運用有不同的方向時,也可以使用這種混合類型:可以在同一個方向上有多個運動,例如“走”和“跑”。在Freeform Directional類型中,(0,0)位置必須包含一個默認(rèn)動作,如“空閑站立”。
2D Freeform Cartesian(2D自由笛卡兒):當(dāng)混合的2個參數(shù)不代表不同的方向時使用。使用Freeform Cartesian,參數(shù)X和Y可以表示不同的概念類型,例如角速度和線速度。舉個例子:“向前走不轉(zhuǎn)向”,“向前跑不轉(zhuǎn)向”,“向前走并右轉(zhuǎn)”,“向前跑并右轉(zhuǎn)”等動作。
如果角色動畫包含站立、走、跑和轉(zhuǎn)向,非常符合2D Freeform Cartesian這種類型。后面以2D Freeform Cartesian舉例說明。
將Blend Type設(shè)置為2D Freeform Cartesian
設(shè)置Blend Type之后,首先需要兩個參數(shù)控制這個Blend Tree。
在Animator中添加兩個float參數(shù):Turn和Forward分別代表轉(zhuǎn)向速度和向前行進速度,然后將這兩個值設(shè)置為混合樹的參數(shù)(注意順序)


然后點擊 + > Add Motion Field 添加下列動畫clip到混合樹動畫列表。(先不管后面的值)

下面,我們可以使用Unity中提供的自動計算Pos值的功能,來自動計算混合樹的閾值。
Positions詳解
每一個Motion都有一個自己的位置,當(dāng)參數(shù)(x,y)靠近這個位置時,這個動畫就會參與混合。離得越近,這個動畫的比重就越大。
選中一個Motion時,圖中的藍點會有選中的狀態(tài);同樣選中混合圖中一個藍點,對應(yīng)的Motion也會有選中的狀態(tài)。

可以拖動混合圖中相應(yīng)的藍點來修改位置,也可以直接修改Motion后面的值。
Compute Positions
Unity提供了自動計算Position的功能。

通過Compute Position下拉菜單可以選擇不同的計算方式:
| 屬性 | 功能 |
|---|---|
| Velocity XZ | 根據(jù)動畫自身的速度,將velocity.x設(shè)置每個動畫的Pos X,將velocity.z設(shè)置Pos Y。適合2D Simple Directional和2D Freeform Directional類型的混合樹。 |
| Speed And Angular Speed | 將動畫的Y軸角速度(弧度每秒)設(shè)置到Pos X,速度設(shè)置到Pos Y。適合2D Freeform Cartesian類型的混合樹。 |
另外,還可以通過 Compute Position -> X Position From 或 Compute Position -> Y Position From 單獨計算X或Y的值。
| 屬性 | 功能 |
|---|---|
| Speed | 動畫的速度 |
| Velocity X | 沿X軸的速度 |
| Velocity Y | 沿Y軸的速度 |
| Velocity Z | 沿Z軸的速度 |
| Angular Speed (Rad) | Y軸的角速度,單位是弧度/秒 |
| Angular Speed (Deg) | Y軸的角速度,單位是角度/秒 |
Rad 和 Deg 分別代表了弧度和角度,弧度π(3.1415...) = 180°
可以根據(jù)項目的需要來選擇,兩種都可行,但是如果X,Y的數(shù)值相差過大的話,在混合圖上顯示會不便于調(diào)試。
在模型的Import Settings面板可以看到動畫的速度

回到我們的混合樹:
參考上面的內(nèi)容,我們可以使用Speed And Angular Speed來計算每個Motion的位置。
選擇Compute Positions中的Speed And Angular Speed
設(shè)置完后,整個混合樹如下圖所示:

現(xiàn)在我們來測試一下,看看怎么樣。

Preview窗口中,記得一定要點擊左上角的播放,動畫才會實時播放看到效果。
混合的原理
動畫混合時,會根據(jù)X和Y兩個值來確定混合的動畫以及各自所占的比重。上面動圖中我們可以看到,拖動紅點時,可以看到不同的節(jié)點上面圓圈在發(fā)生不同的變化,圓圈的大小即這個動畫所占比重的大小。

紅點所在的位置代表了X和Y兩個參數(shù)的值對應(yīng)的位置。橫軸是X,縱軸是Y。
Direct Blending 直接混合
直接混合可以直接將animator的參數(shù)映射到混合樹動畫的權(quán)重。這在什么時候使用呢?如果你想用參數(shù)精確控制混合的動畫,而不是通過以兩個參數(shù)間接控制動畫的混合。

設(shè)置一個direct混合樹時,motion列表中的每一個動畫需要對應(yīng)一個參數(shù),用來控制這個動畫的混合權(quán)重。
難點解析
“大智,這個2D混合樹中的閾值和動畫中的真實速度是對應(yīng)關(guān)系么?”
“其實只要保持對應(yīng)的相對比例就可以,并不一定要真實的速度:”
1、X,Y的值和動畫的實際速度沒有映射關(guān)系。我們也可以將“走”的動畫的Y值設(shè)置的大一些,將跑的動畫設(shè)置的小一些。但是這樣設(shè)置會在表現(xiàn)上不符合玩家的預(yù)期,感覺怪怪的。
2、在手動調(diào)整時,只要點之間的相對位置保持不變,混合效果不會受太大的影響。
3、但是要注意在寫代碼的時候,要根據(jù)調(diào)整過后值的范圍來設(shè)置對應(yīng)的參數(shù)。

“這樣調(diào)整完參數(shù)就感覺整個圖好看了好多,哈哈!”
總結(jié)
“現(xiàn)在你知道混合樹是干嘛的了吧?”
“知道了,混合樹可以根據(jù)參數(shù),混合多個動畫,每個動畫有不同的權(quán)重,這樣就有了很多中間狀態(tài)。”
“想要把混合樹用好,需要多去嘗試一下”
“嗯,我這就準(zhǔn)備把我那個移動的Animator Controller改成混合樹的方式呢”
今日思考題
“正好,給你布置個思考題,實現(xiàn)人物的前后左右走、跑的動態(tài)混合,正好也能用到你的吃雞游戲里”
“收到!我去也!”
“收獲別忘了分享出來!也別忘了分享給你學(xué)Unity的朋友,也許能夠幫到他。”
擴展閱讀
呼~ 今天小新絮絮叨叨的真是夠夠的了。沒講清楚的地方歡迎評論,咱們一起探索。
我是大智,你的技術(shù)探路者,下次見!
別走!點贊,收藏哦!
好,你可以走了。