Unity知識五:Unity中ITween的回調函數的使用

最近在做一個小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方法指定物體。

文章中有不足之處,懇請大家留言指出批評,謝謝!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章