Unity Animation -- 改進動畫效果
使用曲線(Curves)改善動畫?
? ? ? 在上一篇筆記中(
),我們制作了簡單的小球彈跳的動畫,但這個動畫看起來很不自然,小球的彈跳看起來就像是不受重力影響的物體,沒有加速度的影響。要讓小球的彈跳動畫看起來更自然(不使用物理引擎,只使用動畫),我們需要對中間幀進行調(diào)整,在Unity中,這是通過曲線編輯器(Curve Editor)來實現(xiàn)的。前面筆記中所用使用的Animation編輯器的一個部分叫做Dopesheet,它主要是關(guān)鍵幀被設置的地方。? ? ? ? 下面我們來看看Curve編輯器的使用:
? ? ? ? 1. 在場景中選擇小球?qū)挠螒蛭矬w,在Animation Editor中選擇Ball_Bounce動畫。然后在Animation編輯器的下方,點擊Curves打開曲線編輯器。

?????????2. 使用鼠標滾輪或按F鍵進行縮小,直到我們看到了所有三個關(guān)鍵幀以及連接關(guān)鍵幀的曲線

? ? ? ? 在編輯器中顯示的曲線是關(guān)鍵幀之間的中間幀的可視化地表現(xiàn),特別是它們的變化速度非常直觀。如果此時預覽動畫,我們可以在過程中看到這個關(guān)系。在動畫開始的前幾幀,小球緩慢地降低,在中間加速掉落,然后在最后落地的時候變慢了一點。這種類型的變換被稱為easing。我們下面來看看不使用easing時是什么情況。
? ? ? ? 3. 右鍵點擊第一個關(guān)鍵幀,然后在列表中選擇Right Tangent -> Linear;
? ? ? ? ? ? 右鍵點擊中間的關(guān)鍵幀,然后在列表中選擇Left Tangent -> Linear
? ? ? ? ? ? 這樣選擇后,第一個關(guān)鍵幀和中間的關(guān)鍵幀之間的曲線會變成一條直線

? ? ? ? ?我們此時再點擊Play按鈕預覽一下動畫,注意觀察一下和easing方式的區(qū)別(下落過程和彈回過程)
調(diào)整小球的easing
? ? ? ? 1. 右鍵點擊第一個關(guān)鍵幀,選擇Camped Auto重置tangent到原始狀態(tài)
? ? ? ? 2. 右鍵點擊中間的關(guān)鍵幀,選擇Right Tangent -> Linear
? ? ? ? 3. 在Animation編輯器中點擊Play(三角)按鈕預覽一下
? ? ? ? ? ? 現(xiàn)在這個動畫看起來似乎更真實一點了
? ? ? ? 4. 選擇最后一個關(guān)鍵幀,我們可以看到有一個灰色的小的圓柄(handle),這個叫做切線handle(tangent handle)。

? ? ? ? ?5. 拖動這個handle,調(diào)整曲線讓曲線的頂端更加圓滑一點。
? ? ? ? 6. 預覽并不斷調(diào)整tangent handle,讓小球的彈跳看起來更加真實,彈回來的時候,讓動畫看起來好像小球在空中停住了一會兒。
? ? ? ? 7.右鍵點擊中間的關(guān)鍵幀,選擇Both Tangents -> Free,這樣我們可以對這一幀的左右兩側(cè)的切線都進行自由地控制,我們將整體曲線調(diào)整成類似V字形的樣子

創(chuàng)建擠壓動畫關(guān)鍵幀
? ? ? ? 當物體以足夠大的力碰到某個表面時,物體或者這個表面會發(fā)生形變。當撞擊的能量被釋放后,變形的物體會恢復到原來的形狀(盡可能地接近原始形狀)。在動畫中,這個過程被封裝成了稱為squash(擠壓)和stretch(拉伸)的技術(shù)中。
? ? ? ? 先來創(chuàng)建擠壓:
? ? ? ? 1. 在Animation編輯器中,將Playehead放到第一個關(guān)鍵幀位置(0:00),打開關(guān)鍵幀記錄功能(record按鈕按下)

? ? ? ? ?2. 將Playhead移動到第二個關(guān)鍵幀,這個幀是小球觸碰地面的幀。調(diào)整小球的Scale屬性(按R鍵或者調(diào)整Inspector里的Scale屬性,或者直接在動畫編輯器中編輯這個關(guān)鍵幀的Scale屬性),將Scale的Y調(diào)整為0.8

? ? ? ? ?3. 移動小球,讓小球看起來和地面剛剛接觸
? ? ? ? ? ? ? ? 如果此時我們通過拖動Playhead,則我們可以手動地預覽動畫。這個過程稱為scrubbing。我們從頭拖到尾,可以發(fā)現(xiàn)小球現(xiàn)在是有擠壓效果,但從動畫一開始小球就在慢慢地被擠壓(小球還未接觸到地面之前也在變扁)。這不是我們想要得到的效果。
? ? ? ? 4. 將Playehead移動到第一個關(guān)鍵幀(0:00處),選擇Scale屬性對應的菱形點,然后通過Ctrl+C(MAC系統(tǒng)上Command+C)復制一下這個關(guān)鍵幀。
? ? ? ? 5. 將Playhead移動到小球剛剛接觸地面之前的前一幀,然后Ctrl+V(MAC系統(tǒng)上Command+V)粘貼這個關(guān)鍵幀。
創(chuàng)建拉伸動畫關(guān)鍵幀
? ? ? ? 完成了擠壓動畫關(guān)鍵幀之后,接下來我們實現(xiàn)拉伸的關(guān)鍵幀。對于一個橡膠小球來說,當小球回彈時,會出現(xiàn)被拉伸的形狀。
? ? ? ? 1. 將Playhead移動到小球接觸地面后的緊接著的下一幀位置,將Scale的Y調(diào)整到1.2
? ? ? ? 2. 預覽并跳幀調(diào)整一下擠壓和拉伸的關(guān)鍵幀,達到滿意效果后關(guān)閉Recording功能

讓動畫在場景中任意位置都能正常播放
? ? ? ? 現(xiàn)在我們完成了小球彈跳的動畫,但如果我們將小球初始位置移動到場景中的另一個位置時,會發(fā)生什么事情呢?我們想要達到的效果是小球的起始位置在新的地方,然后正常掉落并播放彈跳動畫。但實際上并非如此。
? ? ? ? 我們將小球移動到另一個位置,然后點擊Animaiton編輯器的預覽按鈕(三角形)
? ? ? ? 可以看到,動畫播放時,小球立刻就回到了最初動畫被創(chuàng)建時小球的原始位置上。這是因為關(guān)鍵幀里記錄的信息是原始的信息。我們在Inspector中看到的Transfor Position的設置,是和3D空間里被選擇物體的位置相關(guān)的(世界坐標)。這就麻煩了,我們好不容易制作了一個動畫,但是這個動畫只能在特定位置才能播放,這樣很不靈活。幸運的是,有一種很簡單的方法來解決這個問題。
? ? ? ? 1. 我們撤銷一下小球位置的改動,讓小球回到原始位置,按Ctrl(Command) + Z
? ? ? ? 2.??在Hierarchy窗口中,右鍵創(chuàng)建一個空游戲物體(Create Empty),重命名為BallParent
? ? ? ? 3. 選擇BallParent,在其Inspector屬性中,Transform部分選擇Reset,將其位置重置為(0,0,0)

? ? ? ? ?4. 將Ball拖動到BallParent游戲物體下方,讓它成為BallParent的子物體

? ? ? ? ?5. 移動BallParent到場景中的另一個位置,然后在Animation編輯器中預覽一下動畫,現(xiàn)在小球可以在任意位置上進行彈跳動畫播放了。
? ? ? ? 我們選擇Ball游戲物體,在Inspector中可以看到,小球的位置其實沒有發(fā)生任何變化。但在Unity中,如果一個物體變成了另一個物體的子物體,它的transform值從世界空間變化為了局部空間(from global to local)。也就是說Ball現(xiàn)在transform里的位置信息,是相對于BallParent位置而言的。我們移動了BallParent游戲物體,并不會影響B(tài)all本身動畫里關(guān)鍵幀里的位置。
挑戰(zhàn):小球彈跳動畫完善
? ? ? ? 現(xiàn)實生活中,小球彈跳的樣子是,第一次落地,回彈的距離最大,但也不會回到初始位置。隨后的多次彈跳中,每一次回彈的距離會逐漸變小。接下來請自行實現(xiàn)一下這個效果。
