2016年12月9日 星期五

Day 10: 隨機掉落裝備——Coroutine

接取、替換掉落裝備的機制都完成了,是時候該讓裝備隨機從天上掉下來了。


我會以Instantiate函數來生產掉落的裝備,所以必須把繫著降落傘的掉落裝備也做成Prefab。



完成後,新增一個名為「WeaponSpawn.cs」的Script,打入以下程式碼:


public class WeaponSpawn : MonoBehaviour

{
    //存所有掉落裝備Prefab的陣列

    public GameObject[] weaponPrefabs;
 

    //掉落的Y軸

    public float posY;
 
    //掉落的X軸範圍[minPosX~maxPosX]

    public float minPosX;

    public float maxPosX;


    //兩次掉落裝備之間的時間間隔[minInterval~maxInterval]

    public float minInterval;

    public float maxInterval;



    void Start()

    {
        //開始Coroutine

        StartCoroutine (SpawnCoroutine ());

    }



    IEnumerator SpawnCoroutine()

    {

        while (true) {
            //生產裝備

            Instantiate (weaponPrefabs [Random.Range (0, weaponPrefabs.Length)], new Vector3 (Random.Range (minPosX, maxPosX), posY, -0.1f), Quaternion.identity);

            //暫停

            yield return new WaitForSeconds (Random.Range (minInterval, maxInterval));

        }

    }

}


一開始我宣告了一個名為weaponPrefabs的陣列以儲存每個掉落裝備的Prefab (沒錯,Unity也允許在Inspector中指定陣列的初始值)。

posYminPosXmaxPosX代表Instantiate裝備時的X軸與Y軸,因為掉落裝備會被生產在螢最上方的隨機一處,所以Y座標是固定的,而X座標必須為在兩個邊界值[minPosX, maxPosX]之間的隨機數。

minIntervalmaxInterval定義產生兩次掉落裝備之間的最短與最長時間差。和minPosXmaxPosX一樣,會以Random.Range()取得隨機值。

先跳過void Start()函數,來看回傳型態為IEnumeratorSpawnCoroutine函數。這個函數為Unity Scripting中非常強大的功能之一,Coroutine。Coroutine和一般函數不同之處在於,Coroutine可暫時停止,把控制權交還給Unity,並在暫停後接續執行剩下的程式碼。Coroutine的回傳型態必須是IEnumerator,且內部需至少有一處使用yield return來暫停 (交還控制權)。如果只要暫停一個影格,下一影格繼續,可使用yield return null。然而,生產掉落裝備的暫停區間是以秒數定義的,所以必須使用WaitForSeconds物件。在Coroutine中使用yield return new WaitForSeconds(float s)可以讓Coroutine暫停s秒之後繼續。我以Random.Range()產生隨機區間。

SpawnCoroutine中,yield return new WaitForSeconds(...)上方的Instantiate和先前幾篇文章的用法一樣,不贅述。唯一不同的是Random.Range(0, weaponPrefabs.Length),這個Random.Range的參數是整數(int)型態,所以隨機的區間不包含max值,也就是[min, max)。

回過頭來看Start()函數,以StartCoroutine(SpawnCoroutine())可以讓SpawnCoroutine開始運行。StartCoroutine也可以字串做為參數,如StartCoroutine(“SpawnCoroutine”)。每個Coroutine都必須傳入StartCoroutine()以開始運行,StopCoroutine(string coroutine)可停止Coroutine (是停止,不是暫停),而StopAllCoroutines()可以停止該MonoBehavior中所有的Coroutine。

寫完程式後,回到Unity Editor。在Hierarchy欄中新建一個名為「Weapon Spawn」的Game Object。將Weapon Spawn (Script) Component加到該Game Object上。


把Weapon Prefabs的Size設定為7後,便可把掉落裝備的Prefab一一拉到欄位中,調好剩下欄位的數值後,進入Play Mode測試。裝備現在會隨機從螢幕上方掉落啦!




繪圖進度

畫完結束畫面用以表示高度的地標&大樓:



待續。

沒有留言 :

張貼留言