天天看點

[Unity3d]unity中新老動畫系統

Unity4的Mecanim動畫很早以前就有體驗過,遲遲沒有加到項目中有兩個原因,今天寫這篇部落格來記錄我在做的過程中遇到的一些問題。

1.以前的代碼代碼量比較多,修改起來動的地方太多了。

2.使用Mecanim動畫,還得需要美術的動畫做配合才行。

在3.x中播放動畫的時候使用Play()或CrossFade(),直接播放動畫 或淡入淡出播放動畫。

1 animation.Play("name");

2 animation.CrossFade("name");

也可以使用隊列播放,讓動畫形成一個隊列。

我舉一個我現在項目的例子。主角攻擊敵人是一套連招,連招一共分為4套動畫。也就是當玩家連續按下4次攻擊鍵時這四套動畫是連續播放的,假如玩家隻連續按下2次攻擊,可能隻會播放前兩套動畫。代碼中你需要判斷其中某個動畫是否播放完畢,隻有播放完畢才能繼續播放下一個動畫。

1 if(animation.isPlaying)

2 {

3

4 }

5

6 if(animation.IsPlaying("attack1"))

7 {

8

9 }

大家在仔細想想這個命題,我們可以把動畫分成4中可能的隊列,也隻可能分為這幾種隊列。

站立動畫- 》攻擊動畫0 -》站立動畫

站立動畫- 》攻擊動畫0 -》攻擊動畫1 -》站立動畫

站立動畫- 》攻擊動畫0 -》攻擊動畫1 -》攻擊動畫2-》站立動畫

站立動畫- 》攻擊動畫0 -》攻擊動畫1 -》攻擊動畫2-》攻擊動畫3-》站立動畫

此時如果用unity3以前的動畫方式,無非就是上面這幾種方法加上一些邏輯判斷完成。現在Unity4加入了Mecanim動畫,可以很好的幫我們解決這個問題。詳細的動畫使用教程我就不多說了,網上已經有很多人寫過了。

如下圖所示,以前我們在使用模型的時候。一個原始模型,原始模型中沒有動畫。然後是動畫模型,每一個動畫都會依賴原始模型。動畫的名稱末尾用 名稱 + @name來表示。 這樣的做法使用起來非常友善,但是由于每一個動畫都會依賴原始模型是以檔案會非常大。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%882.14.57.png"></a>

Unity4已經将預設模型與動态導入的類型做了修改,你會發現你的模型拖拽入Hierarchy視圖中沒有Animation元件而是Animator元件。如果你還是想在Unity4中使用以前的動畫系統。你需要把每個模型和動畫的類型改成 Rig-&gt; Animation Type -&gt; Legacy,如下圖所示。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%882.19.04.png"></a>

手動的改起來會非常的累。建議你将下面這條腳本放在項目Editor檔案夾下(沒有建立一個)。這樣當你将模型或動畫拖入Project視圖中,程式會自動幫你修改它的類型,顯然Unity已經不建議大家繼續使用以前的動畫系統了。

01 using UnityEditor;

02

03 public class MyEditor : AssetPostprocessor

04 {

05 public void OnPreprocessModel()

06 {

07 ModelImporter modelImporter = (ModelImporter) assetImporter;

08 modelImporter.animationType = ModelImporterAnimationType.Legacy;

09 }

10 }

下面開始說說新的動畫。在Animations頁籤中先勾掉Import Animation 點選Apply。如下圖所示,在Rig頁籤中修改Animation Type的類型為Humanoid。 如果你希望現在選擇的這個模型做為标準模型的話,在Avatar Definition中選擇Create From This Model。點選下方的Configure可以預覽你的骨骼。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%882.13.32.png"></a>

讓美術修改一下以前的動畫,将動畫中的原始模型去掉,這樣還可以減少檔案的大小。然後在Porject視圖中找一個原始模型拖拽入右側Preview中,可以看到這個模型已經播放奔跑動畫。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%882.33.35.png"></a>

此時換一個模型拖入同樣可以預覽奔跑效果。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%882.36.51.png"></a>

如下圖所示,在動畫的.fbx中 因為動畫需要用剛剛生成的骨骼。是以這裡Avatar Definition中你需要選擇Copy From Other Avatar 。在Source中選擇剛剛生成的Avatar 以後所有動畫都需要這樣來設定。。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%884.38.57.png"></a>

下面我們來讓這個女模型和男模型共用男模型的那一套動畫,在遊戲視圖中播放。在Project視圖中選擇Crate-&gt;AnimatorController。然後把Project中男模型和女模型都拖拽入Hierarchy視圖中。 将剛剛建立的AnimatorController放置在Controller處。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%882.41.31.png"></a>

此時在Unity導航菜單欄中選擇Window -》 Animator。 将動畫檔案拖入Animator視窗中,你會發現兩個模型都開始發生運動。如下圖所示,黃顔色表示它為原始動畫,也就是根動畫。用箭頭将它們一一前後相連,箭頭實際上就是動畫播放的條件。請注意看圖中兩個藍色的箭頭,A播放完後将會播放B動畫,可是B卻對應了兩個箭頭,也就是說B播放完後可以播放C也可以回過頭來播放A。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%883.00.59.png"></a>

那麼B播放完到底是播放C還是播放A呢?用滑鼠點選一下箭頭,看看這這兩個箭頭的條件吧。分别點開BA 和BC的兩個箭頭,在右側監測面闆視圖中你都會發現Conditions下有一個Exit Time的條件。根據動畫的不同對應數值也會不同,我的數值是0.94。也就是當B動畫播放0.94s後将播放下一個動畫。預設BA和BC的動畫時間是一樣的,Unity會有限選擇下一個動畫,也就是A -》 B-》-》C-》D-》A這樣循環播放下去。假設我現在需要動畫是 A-》B-》A這樣循環播放,隻需要修改一下BA箭頭的條件,将Exit Time改小一點隻要比BC箭頭上的小就可以。。 其它的播放虛列原理類似。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%883.09.50.png"></a>

接着還有問題了,用時間來做動畫切換的條件是不是有點太限制了。Animator還支援自定義條件,在Animator視窗的左下角處,點選“+”按鈕就可以添加變量。這裡我添加三組變量, float 、int、bool。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%883.17.50.png"></a>

變量添加完畢後,繼續點選箭頭的條件,箭頭上可以有一個條件 或者多個條件。如果是多個條件需要多個條件同時滿足才可以。 Conditons左鍵是變量名稱,中間是變量條件,右邊是變量值。

Greater 表示左邊變量大于右邊時觸發

Less 表示左邊變量小于右邊時觸發

Equals 表示左邊變量等于右邊時觸發

NotEquals表示左邊變量不等于右邊時觸發。

int 變量上述四種都有,float變量隻有Greater 和Less, bool變量隻有true和false。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%883.20.38.png"></a>

此時我們在加深一下了解。選擇AB的箭頭,也就設定A動畫切換B動畫的條件。

ft     Greater      5 表示 當ft的值大于5的時候觸發。

it      Less           3 表示 當 it的值小于3的時候觸發。

ib     true            表示 當ib的值等于true的時候觸發。

隻有上述三種條件全部達成時将A動畫将切換播放B動畫。否則将一直停留在播放A動畫處。

<a target="_blank" href="http://www.xuanyusong.com/wp-content/uploads/2013/04/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2013-04-16-%E4%B8%8B%E5%8D%883.26.38.png"></a>

那麼ft it ib的這三個變量到底在那裡設定呢?如下圖所示,才記得前面我們建立的三個變量嗎? 這三個變量對應的值就是右邊的 0.0 0 false 。在編輯器中你可以通過修改這三個數值來滿足播放動畫的條件。可是在代碼中怎麼辦呢?

在代碼中你可以這樣來設定或變更它們的條件。 如果說你需要在程式中判斷目前動畫的一些資訊,可以使用 GetCurrentAnimatorStateInfo(0),我查了一下Animator不能直接拿到目前播放動畫的名稱, 隻能拿到它對應的Has值,也就是說你需要将原始的動畫名稱轉換成Hash來判斷。

01 using UnityEngine;

02 using System.Collections;

04 public class NewBehaviourScript : MonoBehaviour {

06 private Animator animator ;

07 void Start()

08 {

09 //得到Animator對象

10 animator = GetComponent&lt;Animator&gt;();

11 }

12

13 void OnGUI()

14 {

15 if(GUILayout.Button("play",GUILayout.Width(50)))

16 {

17 //在這裡設定變量的條件

18 animator.SetFloat("ft",6f);

19 animator.SetInteger("it",2);

20 animator.SetBool("ib",true);

21

22 }

23 }

24

25 void Update()

26 {

27 AnimatorStateInfo animatorState = animator.GetCurrentAnimatorStateInfo(0);

28

29 if(animatorState.IsName("Base Layer.Run_FastStop_Idle"))

30 {

31 Debug.Log("動畫相等");

32 }else

33 {

34 Debug.Log("動畫不等");

35 }

36

37 }

38 }

另外Mecanim還支援多個動畫的混合。目前Mecanim還有一個最大的難題,也是文章最上面我說的需要美術配合的那部分。之前我們看到的動畫都是應用于人型模型,也就是說它支援人形的骨骼, 舉個例子我們的項目人和武器是兩個骨骼,這樣在用Mecanim就悲劇了。因為不同模型武器的骨骼不一樣是以公用模型的話會出現武器位置不對的情況。最後我想到的辦法就是美術将以前做的武器骨骼重新導出,每個人對應一套自己武器骨骼(或者一些特殊的骨骼)最後生成武器的動畫 ,比如 站立動畫、攻擊動畫、死亡動畫等。當Mecanim播放動畫的時候,同時在播放該模型對應的武器動畫,我想這樣就可以解決這個問題吧。

本文轉蓬萊仙羽 51CTO部落格,原文連結:http://blog.51cto.com/dingxiaowei/1366111,如需轉載請自行聯系原作者

繼續閱讀