1. 程式人生 > >Unity 讓物體同時播放兩種動畫

Unity 讓物體同時播放兩種動畫

        在用Unity開發工程中,會遇到需要讓一個物體同時播放兩種動畫的情況,舉個簡單的例子: 一隻小鳥,這隻小鳥會拍翅膀,這隻小鳥也會按一定的軌跡飛行。   實現這個需求有幾種思路:

1. 用動畫控制器控制小鳥拍翅膀的動畫,編寫指令碼控制小鳥的飛行軌跡;

2. 在一個動畫中同時K上 拍翅膀相關的幀 和 運動軌跡相關的幀;

3. 給這隻小鳥加一個父節點,小鳥自身的控制器會控制鳥拍翅膀的動畫,其父節點上掛一個控制器,用來控制器運動軌跡;

4. 採用動畫混合層的方式,由小鳥自身的動畫控制器 直接控制 小鳥拍翅膀及其運動軌跡的動畫。 

本文將會對第 4 種思路進行簡要介紹。

1)新建一個Unity工程,匯入相關資源,圖中的“Bird”已經掛好動畫控制器,並且其“BaseLayer” (第0層)中新建一個 拍翅膀動畫 => “Fly”動畫。此時,小鳥已經具備拍翅膀的表現了。

 

接著,我們需要新建一個動畫層,來實現其飛行軌跡動畫的疊加:

2). 點選下圖中左上角的 “ + ”號,下方便會出現一個新的層 “New Layer ” 也就是動畫層1了(BaseLayer 是動畫層0),此時可以對這個層重新命名。


3) 在新建的層中點選右上角的設定按鈕 ,開啟該層的設定面板,在設定面板中把 weight 的值 設定成1 (當weight 為0 時,該層的動畫不起作用,隨著weight的值增大,動畫權重增大(類似於動畫速度增加),當weight為1時,表示該層中的動畫均為正常速度播放)。

4)在該層中K上控制小鳥移動的動畫 =>  “Move"。


此時,基本功能已經實現,啟動Unity 你便會發現,物體已經具備兩種動畫表現。

在這裡可以擴充套件一些知識, 如何單獨停止第一層(即新建層)動畫,並在一定時候後繼續該層在停止時刻的動畫? ----有兩種方法可以供大家參考。

第一種方法也是常用的方法是 用程式碼設定該層的權重 weight =0 。新建一個指令碼“Bird” ,掛載到小鳥物體上,加入如下程式碼:

當按下鍵盤上按鍵”Q“時,新建層的動畫會停止,只保留”BaseLayer“層的動畫。

這種方向可以有效地停止掉骨骼動畫。 像CS類射擊遊戲中,通過混合動畫,Base層中主要控制角色手部開槍射擊等動畫,在新建的混合層中控制腳步移動的動畫,這種情況可以用上述的方法停止掉新建的混合動畫層。   然而,對”移動旋轉縮放 “ 類動畫不能用這種方法!

本文需求中小鳥的這種  ”拍翅膀“ + ”拍翅膀“ 組合而成的動畫,不能用設定權重weight的方式去停止動畫 , 這是因為當你把新建的混合層動畫權重設定成0時,物體會回到移動動畫第一幀的位置,並不是在原點待命!

對於”骨骼動畫“ + ”移動動畫“ 這類的,我們可以這樣解決:

1)在新建的混合層中新增一個空的動畫State ,命名可隨意為,並把write defaults 這個選項勾去掉;


2)在常用於播放動畫的 animator.Play() 方法中有5個過載,其中有一個過載方法是可以自行決定動畫從哪裡開始播放的,呼叫此方法我們需要知道兩個關鍵的數值:

stateNameHash 和 normalizedTime。

3)在停止動畫前 先獲取 ”Move“ 動畫當前已經播放了多少(該值為0 到1 ,1 為100%,0.1為10%),即“normalizedTime”。獲取程式碼如下,相關解釋已經備註在程式碼裡:

4)獲取混合層中當前動畫的 名字所對應的雜湊值 => nameHash. 


5)此時準備工作已經完成,下面貼出全部程式碼。小鳥飛行過程中按下 鍵盤”W“鍵,小鳥會保持“拍翅膀”狀態 原地停止3秒,3秒後繼續飛行。

 

其實在物體有固定移動路線時,給物體新增一個父節點,物體自身K骨骼動畫,父節點K帶動物體移動的動畫也是可行的,停掉移動動畫只需要禁用父節點的動畫控制器即可,再次啟動也就是把父節點的控制器再次啟動,動畫也能繼承停止時刻的狀態繼續播放,在邏輯控制上簡單很多,但是隨意給物體新增一個父節點有時有打亂物體之間的結構規律,所以並不推薦這樣做。 

到此,功能已基本實現。

(有什麼錯誤的地方也請各位大大不吝指出~~~)