Unity教學 2D小遊戲製作 part 2
我們這篇要來講物件的產生,和彼此間的碰撞
前一篇講過的東西,這篇都會直接帶過
所以建議先看過前一篇再來看這篇
本篇分5個小節:
1. 飛彈製作
2. 消除子彈的牆壁
3 敵人的產生
4. 消滅敵人的牆壁
5. 敵人撞到子彈或飛機,同時消滅
1. 飛彈製作
首先,先用小畫家畫10 X 50像素的藍色長方型
作為飛機的雷射子彈
畫好後存成PNG檔
把它拖曳到ASSET裡,再拖曳到場景裡
成為一個叫Laser的物件
1. 加入Box Collider 2D和Rigidbody 2D
2. Rigidbody 2D底下,Gravity改成0,不受重力影響
3. Fixed Angle打勾,角度固定 (新版是Freeze Rotation Z打勾)
新版本的Fixed Angle換位置了
在Constraints底下的Freeze Rotation Z打勾
然後加入描述程式
在void Update()底下加入
gameObject.transform.position += new Vector3(0,0.1f,0);
這樣他就會在Y方向不斷增加0.1,也就是一直往Y方向移動
接著把Laser這個物件的名稱改成LaserObject
對著Laser按右鍵,選Rename
改成LaserObject,以便跟Laser的圖片做區分
接著把LaserObject拉到Asset裡,就會複製一個到Asset裡
然後刪除Hierarchy裡的LaserObject
因為我們是要按發射鍵時,才會產生這個雷射子彈
不需要他一開始就在場景裡
然後打開前一回寫的ShipControl
在開頭加上
public GameObject Bullet; 宣告一個物件叫Bullet
然後在void Update()底下加入
if (Input.GetKeyDown(KeyCode.Space))
{
Vector3 pos = gameObject.transform.position + new Vector3(0,0.6f,0);
Instantiate(Bullet,pos,gameObject.transform.rotation);
}
上一回有用過GetKey
GetKey和GetKeyDown的差別
GetKey是按著可連發
GetKeyDown是按下去一次只算一次
if (Input.GetKeyDown(KeyCode.Space)) 如果按下空白鍵,就會觸發大括號裡的描述
我們跳過一行,先講下面的Instantiate
Instantiate(Bullet,pos,gameObject.transform.rotation);
Instantiate就是產生物件的指令
他的格式是
Instantiate(物件, 初始位置,初始角度)
這邊物件就用我們剛剛設定的Bullet
初始位置設pos
初始角度就同飛機的角度
讓我們再回到前一行
Vector3 pos = gameObject.transform.position + new Vector3(0,0.6f,0);
這行是說,宣告一個位置pos
這個位置等於飛機的位置再加上0.6,也就是在飛機的前端
如果我們從飛機的中心位置產生子彈,子彈會馬上撞到飛機
讓子彈和飛機都彈開
然後我們按存檔
回到飛機的物件,我們會看到他的描述程式底下會出現一個Bullet的空格
後面寫None代表尚未指定
接著把LaserObject拖曳到Bullet的空格裡
存檔Ctrl+S後,按PLAY
測試子彈能不能發射
成功的話,會看到很多LaserObject(Clone)的物件
2. 消除子彈的牆壁
這邊會產生一個問題,射出去的子彈會一直往前飛,無法消除
最後累積太多子彈,然後當機
所以我們要在場景外面做一道牆
讓子彈撞到牆,然後消滅
GameObject -> Create Empty
開一個空的物件,改名為TopSide
1. 位置Y設5,X和Z設0
2. 加入Box Collider 2D
3. Is Trigger打勾,撞到東西時會觸發事件
4. Size X=6, Y=0.5
5. 加入程式描述
增加Trigger事件的Function
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "Bullet")
{
Destroy(col.gameObject);
}
}
void OnTriggerEnter2D(Collider2D col)
觸發開始時,執行大括號內的動作,觸發事件的名稱是col
if (col.tag == "Bullet")
如果引起觸發的物件的標籤是Bullet,就執行大括號內的動作
Destroy(col.gameObject);
消滅引起觸發的物件
接著,把LaserObject的標籤設成Bullet
按Add Tag新增標籤
按"+"新增,輸入Bullet
選項裡就會有Bullet可選了
存檔Ctrl+S後,按PLAY
測試子彈撞到牆壁會不會消失
本篇要講的功能就是這兩個,物件的產生和碰撞觸發
之後都是做一樣的動作,讓我們重複練習一下
3 敵人的產生
用小畫家畫一個外星人
拖曳到Asset,再放到場景裡
加入設定
1. 標籤 Emeny
2. 加Box Collider 2D,然後Is Trigger打勾
3. 加Rigidbody 2D,Gravity設0
4. Fixed Angle固定角度打勾 (新版是Freeze Rotation Z打勾)
新版本的Fixed Angle換位置了
在Constraints底下的Freeze Rotation Z打勾
加入描述程式
在void Update()底下加入
gameObject.transform.position += new Vector3(0,-0.01f,0);
Y方向-0.01,緩慢得往下移動
然後改名成InvaderObject,拉到Asset裡
然後刪除Hierarchy裡的InvaderObject
在Background背景物件裡加入程式描述
開頭
public GameObject Emeny; //宣告物件,名稱Emeny
public float time; //宣告浮點數,名稱time
然後在void Update()底下加入
time += Time.deltaTime; //時間增加
if(time>0.5f) //如果時間大於0.5(秒)
{
Vector3 pos = new Vector3(Random.Range(-2.5f,2.5f),4.5f,0); //宣告位置pos,Random.Range(-2.5f,2.5f)代表X是2.5到-2.5之間隨機
Instantiate(Emeny,pos,transform.rotation); //產生敵人
time = 0f; //時間歸零
}
然後把InvaderObject,拉到Emeny的空格
存檔Ctrl+S後,按PLAY
然後我們就會看到很多外星人了
4. 消滅敵人的牆壁
無限的外星人也是會當機的
所以我們在畫面下方加一道牆來消滅這些外星人
加入空物件GameObject → Create Empty
改名為Bottom Side
1. position Y設-5,X和Z設0
2. 加入Box Collider 2D
3. Is Trigger打勾
4. Size X=6, Y=0.5
5. 加入程式描述
跟上方的牆的描述一樣
只差在tag標籤是Emeny
void OnTriggerEnter2D(Collider2D col) //碰撞事件
{
if (col.tag == "Emeny") //如果標籤是Emeny
{
Destroy(col.gameObject); //消滅碰撞的物件
}
}
5. 敵人撞到子彈或飛機,同時消滅
在InvaderObject的程式描述裡
加入觸發事件
void OnTriggerEnter2D(Collider2D col) //名為col的觸發事件
{
if (col.tag == "Ship" || col.tag == "Bullet" ) //如果碰撞的標籤是Ship或Bullet
{
Destroy(col.gameObject); //消滅碰撞的物件
Destroy(gameObject); //消滅物件本身
}
}
最後設定飛機的標籤Ship,就大功告成囉
到此,遊戲的基本功能都有了,只是有點單調
下一篇,會講動畫和音效,讓你的遊戲活起來!
前往下一篇
參考文件:
勇者拉德小酒館 Unity-射擊遊戲系列(1/?) 玩家子彈射擊
http://jerrard-liu.blogspot.tw/2014/11/ShootingGame1.html