(本篇文章網誌版:http://shineright.blogspot.tw/2016/12/day-8-prefab-instantiate.html)
今天我要介紹Unity兩個強大的功能──Prefab和Instantiate。讓主角把接到的裝備戴在頭上。
打開上次寫好的「FallingWeapon.cs」,刪掉「print(“接到了”);
」這行,加入新的程式碼:
public class FallingWeapon : MonoBehaviour
{
public GameObject weaponPrefab; //裝備Prefab
void OnTriggerEnter2D(Collider2D col)
{
//主角接到裝備
if (col.gameObject.tag == "Player") {
//產生裝備
GameObject weapon = (Instantiate (weaponPrefab, new Vector3(col.gameObject.transform.position.x, col.gameObject.transform.y, -0.1f), Quaternion.identity) as GameObject);
//將裝備設為主角的子物件
weapon.transform.parent = col.gameObject.transform;
//移除掉落的裝備
Destroy (gameObject);
}
}
}
我為FallingWeapon加了一個GameObject
型態的public
變數,等一下會把該變數設為裝備的「預製物件」(Prefab)。Prefab簡而言之是預先製作好的Game Object,可隨時拖入場景或從Script中產生(Instantiate)(稍後會說明如何製作Prefab)。通常會將一再重複使用的Game Object做成Prefab。
在OnTriggerEnter2D
的if
判斷式我把print(“接到了”)
這段測試用的程式碼刪掉,改為實際產生裝備的程式碼。呼叫Instantiate(Object obj, Vector3 position, Quaternion rotation)
函數可在場景上生產obj
物件,並將其座標、代表旋轉的四元數設為position
和rotation
。在此,我將生產weaponPrefab
物件,將其座標設為new Vector3(col.gameObject.transform.position.x, col.gameObject.transform.position.y, -0.1f)
。前兩個參數是主角的XY軸,使裝備產生在和主角一樣的XY軸座標上。Vector3的第三個參數是Z軸,我設定為-0.1f是因為主角的Z軸是0,要使裝備顯示在主角前面,裝備的Z軸必須小於主角的Z軸(但不能小於Main Camera的Z軸)。四元數Quaternion.identity
是Quaternion
類別定義的靜態常數(Static Constant),代表「沒有旋轉」的四元數。
因為Instantiate
的回值型態是Object
,所必須在後面用as GameObject
把他轉成GameObject
型態,以便在後面取得它的transform
成員。
weapon.transform.parent = col.gameObject.transform;
上面這行程式碼,把新產生weapon
物件的parent設為主角(也就是col.gameObject
)。這麼做跟在Hierarchy欄把weapon
拖到主角上有一樣的效果,也就是把weapon
變成主角的子物件。如此,當主角移動時,因為weapon
是它的子物件,所以也會跟著移動。
最後,我將掉落裝備自身的gameObject
傳入Destroy
函數,使掉落裝備移除自己,以免在主角接到裝備後持續掉落。
程式碼打好了,接著來製作Prefab吧!事實上製作Prefab非常容易,只要把Game Object從Scene上拉回Project欄就好了。把要做成Prefab的裝備的圖片從Project欄中拉到Scene視窗
使它成為一個擁有SpriteRenderer Component的Game Object。再把這個新的Game Object從Hierarchy欄拉到Project欄,裝備的Prefab就做好了。(可以看到Hierarchy欄中的裝備名稱變成藍色的,代表它是一個Prefab)。
接著,把製成Prefab的裝備從Scene中刪除。回去點選附著降落傘的「掉落裝備」,在Inspector欄中的Falling Weapon (Script) Component,把Weapon Prefab欄設為剛剛做好的Prefab。
進入Play Mode測試一下,一切運作順利,但主角接到的武器會直接疊在臉上,而不是戴在頭上。會如此是因為我們在Instantiate
裝備時,把座標設定為和主角一樣的座標。要修改這個問題,可以把裝備擁有Sprite Renderer的Game Object設為另一個Game Object的子物件,並調整子物件在新的Game Object中的座標。
聽起來很複雜,但實際做一遍就會清楚了。先在Hierarchy欄新建一個空的Game Object,命名為想要的裝備名稱(我把它命名為「Death Cap」),並在Inspector中把Transform Component的Position設成和主角一模一樣。
接著把裝備的Sprite拉到Hierarchy中的「Death Cap」上,命名為「Sprite」(表示該Game Object是擁有Sprite Renderer Component的物件)。
再到Scene視窗把「Sprite」這個Game Object拉到主角的頭上。
完成後把舊的裝備Prefab刪掉,把新的「Death Cap」拉到Project欄成為新的Prefab。
到Falling Weapon (Script) Component把Weapon Prefab欄設為新做好的Prefab。
進入Play Mode,現在主角會將裝備戴至頭上了。
敵人、敵人子彈和敵人死掉的畫面大致畫完了。
待續。