最近在做一個小Demo,用到ITween來完成部分動畫的功能,令我苦惱的是ITween的執行過程讓我很無奈,源代碼片斷如下:
//OnMouseUpAsButton()是Unity提供的點擊方法
public void OnMouseUpAsButton(){
//點擊之後左邊的門向右移動,右邊的門向左移動,是關門的動畫
iTween.MoveTo (leftDoor,new Vector3(-2.26f,0f,-0.1f),1.0f);
iTween.MoveTo (rightDoor,new Vector3(2.26f,0f,-0.1f),1.0f);
//之後,左邊的門向左移動,右邊的門向右移動,是開門的動畫
iTween.MoveTo (leftDoor,new Vector3(-6.0f,0f,-0.1f),1.0f);
iTween.MoveTo (rightDoor,new Vector3(6.0f,0f,-0.1f),1.0f);
}
我原先以爲它會按照我想的去移動,至少也是移動有先後順序,上面的語句執行完了才能執行下面的語句,但是事實上,這四行代碼不是四秒運行完的,而是在同一秒中運行完畢,所以沒有動畫。
就像我現在往一個空籃子中撿雞蛋,我想把雞蛋全都撿到籃子裏之後,再撿出來,現在卻是你在把雞蛋撿進籃子的同時,旁邊還有個熊孩子正在往外撿雞蛋,所以到頭來,籃子裏還是沒有雞蛋。
遇到這種情況怎麼辦呢?那就是你要告訴這個孩子:等我把雞蛋全撿到籃子裏之後,你再往外撿。
那麼我們就知道了:要告訴Unity,關門的動畫完成之後才能開始開門的動畫。
怎麼告訴呢?
網上給的答案有些模棱兩可,不是很清晰,現在以我的項目爲例給出詳細的解決方法:
首先大家要了解的一件事就是ITween的MoveTo()等方法裏的參數不僅僅是(目標物體,目標位置,事件),更多的動畫控制存在一張自定義的哈希表中。哈希表中有一個重要的參數就是回調函數。
ITween爲我們提供了三個回調函數:onstart、onupdate和oncomplete。爲什麼函數後面沒有帶括號,我們等下說。
它們的意思分別是:在當前動畫開始執行的時候執行、在當前動畫執行的每一幀中執行、在當前動畫執行完成後執行。
那麼我們本例中理所當然就用到了最後一種。
接下來看看怎麼用:
using UnityEngine;
using System.Collections;
public class StartIntferface : MonoBehaviour {
//下面四個使我們要操作的對象,分別是logo、按鈕、左邊的門、右邊的門
public GameObject logo;
public GameObject Btn;
public GameObject leftDoor;
public GameObject rightDoor;
//爲OnComplete()方法制定物體,詳情見下方
public GameObject completeObject;
//分別給兩個門聲明一個哈希表,哈希表中當然存儲的就是控制動畫的信息了
Hashtable leftDoorClose=new Hashtable();
Hashtable rightDoorOpen=new Hashtable();
// Use this for initialization
void Start () {
//在Start ()中爲哈希表添加信息屬性
leftDoorClose.Add ("time",1.0f);//門關閉所需的時間
leftDoorClose.Add ("position",new Vector3(-2.26f,0f,-0.1f));//門最終的位置(門要移到什麼地方去)
leftDoorClose.Add ("oncomplete","OnComplete");//動畫完成後執行什麼方法,OnComplete在下面
leftDoorClose.Add ("onCompleteTarget",completeObject);//這個屬性看代碼下方
//上面是左邊的門,下面是右邊的門,因爲它們要移動的位置不同,所以不能共用一個哈希表
rightDoorOpen.Add ("time",1.0f);
rightDoorOpen.Add ("position",new Vector3(2.26f,0.0f,-0.1f));
rightDoorOpen.Add ("oncomplete","OnComplete");
rightDoorOpen.Add ("onCompleteTarget",completeObject);
//遊戲一開始logo平移下來
iTween.MoveTo (logo,new Vector3(0,1.5f,0),1.0f);
iTween.MoveTo (Btn,new Vector3(0,3.2f,-0.9f),0.5f);
}
// Update is called once per frame
void Update () {
}
//OnMouseUpAsButton()這個方法是Unity官方提供的響應交互方法,當前腳本給了誰,鼠標點擊那個物體,響應這個方法(前提是物體加了Collider或者GUIElement組件)
public void OnMouseUpAsButton(){
//方法的一開始是對logo和按鈕的簡單操作
iTween.MoveTo (logo,new Vector3(0,4.463f,0),1.0f);
iTween.MoveTo (Btn,new Vector3(0,0.0f,-0.9f),0.5f);
//這裏是ITween根據哈希表中的信息對目標物體進行操作
iTween.MoveTo (leftDoor,leftDoorClose);
iTween.MoveTo (rightDoor,rightDoorOpen);
}
//上面的leftDoorClose.Add ("oncomplete","OnComplete")和rightDoorOpen.Add ("oncomplete","OnComplete")中用到的方法就是這個OnComplete()方法。當然了你也可以定義成別的名稱
private void OnComplete(){
//這裏就是開門的動畫咯
iTween.MoveTo (leftDoor,new Vector3(-6.0f,0f,-0.1f),1.0f);
iTween.MoveTo (rightDoor,new Vector3(6.0f,0.0f,-0.1f),1.0f);
}
}
好了,代碼就寫完了,但是要回頭解釋一下:leftDoorClose.Add (“onCompleteTarget”,completeObject)這句是什麼意思呢?
字面意思是onComplete的目標物體,那麼爲什麼會有這個東西呢?
用過ITween的同學都知道,把物體S從A移動到B位置,物體S身上會多一個ITween的腳本,有了這個腳本它纔會移動,移動完成後就會移除,物體S從A移動到B位置之後,根據需要會選擇性執行onComplete方法,所以物體S身上可能還會被ITween加上一個onComplete腳本,但是物體S在執行onComplete腳本的時候會發現:哎,我身上沒有onComplete()方法啊,我是被控制的物體,onComplete()方法在控制我移動的那個物體身上啊。
因此,我們就要爲onComplete()指定它所在的物體,這也是我們爲什麼定義了一個completeObject物體的原因。
我們回到unity,把上面這個StartIntferface腳本拖給StartBtn物體,爲什麼要拖給它?因爲OnMouseUpAsButton方法呀,我點擊開始按鈕的時候響應,那麼這個方法只能放在我要點擊的物體上:
大家可以對比一下,看看物體的對應關係:
我們可以運行了:
有的朋友會問:這裏只是兩個動畫之間的過渡,那麼我有三個甚至更多個怎麼辦呢?
方法類似嘛:
我們在OnComplete()方法中寫了很簡單的兩個MoveTo,這個MoveTo裏面同樣可以填上覆雜的哈希表,哈希表中的oncomplete指向另一個方法比如OnComplete2(),就好啦,同樣的還可以有OnComplete3()、OnComplete4()、OnComplete5()嘛。
好了,完整的小demo就是這樣啦,這裏值得注意的就是哈希表的使用和onComplete方法以及爲onComplete方法指定物體。
文章中有不足之處,懇請大家留言指出批評,謝謝!!