(本篇文章網誌版:http://shineright.blogspot.tw/2016/12/day-7-random-destroy.html)
今天終於要讓掉落裝備以隨機的初始速率緩緩下降,以及讓裝備在離開螢幕(也就是Main Camera)時自動被移除。
要讓裝備下降有幾種方式,其中一種是把掉落裝備的Rigidbody 2D Component的Is Kinematic取消,裝備就會隨著地心引力(gravity)直直落下。然而,這種方式無法讓掉落裝備在下降的過程維持同一速率。
所以,只好自己寫點Script啦!
新建一個名為「RandomInitialSpeed.cs」的C# Script,並為掉落裝備新增這個Component。
using UnityEngine;
using System.Collections;
public class RandomInitialSpeed : MonoBehaviour
{
public Vector3 minSpeed; //最低速度
public Vector3 maxSpeed; //最高速度
private Vector3 speed; //以隨機選定的速度
void Start()
{
//把speed設為在minSpeed和maxSpeed之間的向量
speed = new Vector3 (Random.Range (minSpeed.x, maxSpeed.x), Random.Range (minSpeed.y, maxSpeed.y));
}
void Update()
{
//每一影格隨過去的時間移動
transform.Translate (speed * Time.deltaTime);
}
}
雖然掉的裝備只沿y軸緩緩下降,但上段Script宣告的minSpeed
和maxSpeed
都是擁有X軸、Y軸、Z軸的向量。如此,以後要使敵人左右移動或橫向移動,都可以重複使用這段Script。
在Start()
函數中,我以Random.Range()
函數取得介於minSpeed
和maxSpeed
之間的向量。Random.Range(float min, float max)
會回傳一個[min
, max
]之間的隨機浮點數。
Update()
函數中,我以transform.Translate()
移動掉落裝備。transform.Translate(Vector3 movement)
會使Game Object往movement
向量移動。和之前一樣,把speed
乘上Time.deltaTime
,才能使物體隨著時間而不是影格數移動。
點擊掉落裝備,調整一下Random Initial Speed (Script) Component的minSpeed
和maxSpeed
。因為我只想讓裝備在y軸緩緩下降,所以設定Y的數值即可(我是把minSpeed
設為(0, -0.75, 0)、maxSpeed設為(0, -2.25, 0)。
進入Play Mode測試一下,現在掉落裝備會緩緩下降了。
在讓主角可以穿戴裝備之前,我先來處理落到螢幕範圍外的裝備。
或許你會想,落到螢幕範圍外的裝備不就看不到了嗎,為什麼還要寫Script把它移除掉?事實上,就算玩家在螢幕上看不到落到下方的裝備,但它們仍存在於遊戲場景上。換句話說,它還佔用著記憶體。更糟的是,每次進入新的影格,它們的Random Initial Speed (Script) Component中的Update()
函數仍會被呼叫。所以當掉落裝備數量愈來愈多,遊戲便逐漸邁向當機之路。
移除裝備的方式很簡單。可以在Update()
函數中檢查Game Object的transform.position
是否超出邊界,若超出邊界,就移除該Game Object。
不過,我要用一個更簡單的方法。在Hierarchy欄中建立一個新的Game Object,命名為「Boundary Collider」,並為它新增一個Box Collider 2D Component。把它拉至螢幕下方,超出Main Camera一點點,再以Box Collider 2D Component的Edit Collider鈕拉寬Collider範圍,使所有掉落的裝備在離開螢幕時,都會落到這個Collider上。
把Box Collider 2D Component的Is Trigger欄打勾,並新建一個名為「DestroyGameObjectOnTrigger.cs」的C# Script。
using UnityEngine;
using System.Collections;
public class DestroyGameObjectOnTrigger : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D col)
{
Destroy (col.gameObject);
}
}
這段程式碼非常簡短且明瞭。當任何Collider 2D進入Trigger範圍,就把擁有該Collider 2D的Game Object移除(Destroy)掉。Destroy(Object obj)
是一個非常方便的函數,它會把obj從場景中移除。甚至可以在Script中以Destroy(gameObject)
把自身移除。
進入Play Mode,可以在Hierarchy欄看到落出螢幕範圍的裝備被移除了。
繼續趕工畫敵人。
待續。