close
  • 此篇重點語法 * * * * *

利用iTween做到讓物體沿著路徑移動,並保持正向移動

 

  •  此篇效果 – iTween讓物件沿著自訂路徑移動,並保持正向移動 

上集教學我們講到有關iTween沿著Path行走,這篇主要是要延續上篇內容,在沿著Path同時朝著前方轉向

 

  • 此篇重點教學 * * * * *

實作這個朝正向移動的功能,在Unity有很多解法,而最直覺的就是算出他每單位時間的移動方向,來轉動他的方向

 

這功能可以分割成下列幾的部分

  1. 將下一個時間點位置減掉上一個時間點的位置,藉此算出他的移動方向
  2. 將此位移方向,轉成角度並賦予在物件身上
  3. 若還沒到盡頭就重複1.2兩點

 

假設在每個時間點間格,我們將他設為0.01秒,而這功能在update()函式中要實作此功能是較不建議的,有可能會影響到遊戲中的其他功能,所以我們就自己來寫一個類似update()的函式吧!

為此我們必須用到IEnumerator或是InvokeRepeating()的做法,因為InvokeRepeating()要做到完全的隨時開關比較麻煩,這邊就用IEnumerator和他的對應函式StartCoroutine()來實作,他可以讓程式執行時以一個類似Thread的方式執行

註:IEnumerator並沒有開新的Thread,主要還是在Main Thread

 

這邊我們先加入幾行程式碼


    void Start () {

        MoveByPath();

        StartCoroutine(RotateObject());

    }

 

    IEnumerator RotateObject(){

    }


這就代表在開始時,會多開一個線程去運作RotateObject()的內容

而此線程函式在裡面要做到上述的三個部分,其程式碼如下


    IEnumerator RotateObject(){

        prev = transform.position;

        while (!finish){

            yield return new WaitForSeconds((float) 1 / FPS);

            Vector3 direc = transform.position - prev;

            transform.eulerAngles = new Vector3(0 , Mathf.Atan2(direc.x, direc.z) * Mathf.Rad2Deg , 0);

            prev = transform.position;

        }

    }


 

prev = transform.position;

用來記錄初始位置,供單位時間後判斷移動方向

 

yield return new WaitForSeconds((float) 1 / FPS);

yield return 是IEnumerator 中常用的一個用法,可以等一段時間或是其他函式完全做完才執行,這行代表停止 1 / FPS 秒,此FPS可自行設定

 

Vector3 direc = transform.position - prev;

算出其位移方向

 

transform.eulerAngles = new Vector3(0 , Mathf.Atan2(direc.x, direc.z) * Mathf.Rad2Deg , 0);

改變物體角度,Atan2可以依物體移動的兩軸向量算出其角度,再乘上他的旋轉角度(360/2π),在這邊只需要改變他的Y軸平面轉度就好

 

 

這樣計算其旋轉的程式碼就完成了,在最後當物體到達目的地時,再將finish tag改成true,以減低系統的效能,這在iTween設置要多加一行,執行ChangeFinishTag() 函式

moveSetting.Add("oncomplete", "changeFinishTag");

 

void ChangeFinishTag(){

    finish = true;

}

 

整體的程式碼會向下面這樣


    public Vector3 prev;

    public bool finish = false;

    readonly int FPS = 100;

 

    // Use this for initialization

    void Start () {

        MoveByPath();

        StartCoroutine(RotateObject());

    }

 

    IEnumerator RotateObject(){

        prev = transform.position;

        while (!finish){

            yield return new WaitForSeconds((float) 1 / FPS);

            Vector3 direc = transform.position - prev;

            transform.eulerAngles = new Vector3(0 , Mathf.Atan2(direc.x, direc.z) * Mathf.Rad2Deg , 0);

            prev = transform.position;

        }

    }

 

    void ChangeFinishTag(){

        finish = true;

    }

 

    void MoveByPath(){

        Hashtable moveSetting = new Hashtable();

        moveSetting.Add("time", 5.0f);

        moveSetting.Add("easetype", iTween.EaseType.linear);

        moveSetting.Add("path", iTweenPath.GetPath("PathTest"));

        moveSetting.Add("oncomplete", "changeFinishTag");

 

        iTween.MoveTo(this.gameObject , moveSetting);

    }


 

接下來實際讓他跑看看吧!

這樣就完成讓物體隨著路徑移動並且,朝著路徑前進了!

 

若有其他實作的方式歡迎提出討論,我們都很樂意與您討論的XD

arrow
arrow

    twilighthook 發表在 痞客邦 留言(0) 人氣()