27.jpg  

 

承接上一篇Unity教學 2D小遊戲製作 part 1

我們這篇要來講物件的產生,和彼此間的碰撞

前一篇講過的東西,這篇都會直接帶過

所以建議先看過前一篇再來看這篇 

 

本篇分5個小節:

1. 飛彈製作

2. 消除子彈的牆壁

3 敵人的產生

4. 消滅敵人的牆壁

5. 敵人撞到子彈或飛機,同時消滅

 

 

 

1. 飛彈製作

首先,先用小畫家畫10 X 50像素的藍色長方型

作為飛機的雷射子彈

1  

 

畫好後存成PNG檔

把它拖曳到ASSET裡,再拖曳到場景裡

成為一個叫Laser的物件

2.JPG

 

1. 加入Box Collider 2D和Rigidbody 2D

2. Rigidbody 2D底下,Gravity改成0,不受重力影響

3. Fixed Angle打勾,角度固定 (新版是Freeze Rotation Z打勾)

3.JPG  

  

新版本的Fixed Angle換位置了

在Constraints底下的Freeze Rotation Z打勾

36.JPG  

 

然後加入描述程式

4.jpg  

 

void Update()底下加入

gameObject.transform.position += new Vector3(0,0.1f,0);

這樣他就會在Y方向不斷增加0.1,也就是一直往Y方向移動

5.JPG  

 

接著把Laser這個物件的名稱改成LaserObject

對著Laser按右鍵,選Rename

6.jpg  

 

改成LaserObject,以便跟Laser的圖片做區分

7.jpg  

 

接著把LaserObject拉到Asset裡,就會複製一個到Asset裡

7-1.JPG  

 

然後刪除Hierarchy裡的LaserObject

因為我們是要按發射鍵時,才會產生這個雷射子彈

不需要他一開始就在場景裡

7-2.jpg  

 

然後打開前一回寫的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

初始角度就同飛機的角度

8.JPG  

 

讓我們再回到前一行

Vector3 pos = gameObject.transform.position + new Vector3(0,0.6f,0);

這行是說,宣告一個位置pos

這個位置等於飛機的位置再加上0.6,也就是在飛機的前端

如果我們從飛機的中心位置產生子彈,子彈會馬上撞到飛機

讓子彈和飛機都彈開

9.JPG  

 

然後我們按存檔

回到飛機的物件,我們會看到他的描述程式底下會出現一個Bullet的空格

後面寫None代表尚未指定

10.JPG  

 

接著把LaserObject拖曳到Bullet的空格裡

11.JPG  

 

存檔Ctrl+S後,按PLAY

測試子彈能不能發射

25_1.JPG  

 

成功的話,會看到很多LaserObject(Clone)的物件

12.jpg  

 

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. 加入程式描述

13.JPG  

 

增加Trigger事件的Function

注意!這段程式碼不是放在void Update()的大括號{}裡面

是放在void Update()的大括號{}的後面(詳見圖片)

放錯位置程式碼可能會無效,子彈就不會消失

void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "Bullet")
{
Destroy(col.gameObject);
}
}

14_1.jpg

void OnTriggerEnter2D(Collider2D col)

觸發開始時,執行大括號內的動作,觸發事件的名稱是col

if (col.tag == "Bullet")

如果引起觸發的物件的標籤是Bullet,就執行大括號內的動作

Destroy(col.gameObject);

消滅引起觸發的物件

 

 

接著,把LaserObject的標籤設成Bullet

按Add Tag新增標籤

15.jpg  

 

按"+"新增,輸入Bullet

16.JPG  

 

選項裡就會有Bullet可選了

17.jpg  

 

存檔Ctrl+S後,按PLAY

測試子彈撞到牆壁會不會消失

25_1.JPG

 

本篇要講的功能就是這兩個,物件的產生和碰撞觸發

之後都是做一樣的動作,讓我們重複練習一下

 

 

3 敵人的產生

用小畫家畫一個外星人

19.JPG  

 

拖曳到Asset,再放到場景裡

20.JPG  

 

 加入設定

1. 標籤 Emeny (經網友提醒,正確拼法是Enemy。我從頭到尾都拚錯,所以程式還是能執行)

2. 加Box Collider 2D,然後Is Trigger打勾

3. 加Rigidbody 2D,Gravity設0

4. Fixed Angle固定角度打勾 (新版是Freeze Rotation Z打勾)

21.JPG  

 

新版本的Fixed Angle換位置了

在Constraints底下的Freeze Rotation Z打勾

36.JPG  

 

加入描述程式

21-1.JPG  

 

void Update()底下加入

gameObject.transform.position += new Vector3(0,-0.01f,0);

Y方向-0.01,緩慢得往下移動

21-2.JPG  

 

然後改名成InvaderObject,拉到Asset裡

22.JPG  

 

然後刪除Hierarchy裡的InvaderObject

23.jpg  

 

在Background背景物件裡加入程式描述

24.jpg  

 

開頭

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; //時間歸零
}

25.JPG  

 

然後把InvaderObject,拉到Emeny的空格

26.JPG  

 

存檔Ctrl+S後,按PLAY

25_1.JPG  

 

然後我們就會看到很多外星人了

27.jpg  

 

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. 加入程式描述

28.JPG  

 

跟上方的牆的描述一樣,只差在tag標籤是Emeny

注意!這段程式碼不是放在void Update()的大括號{}裡面

是放在void Update()的大括號{}的後面(詳見圖片)

void OnTriggerEnter2D(Collider2D col) //碰撞事件
{
if (col.tag == "Emeny") //如果標籤是Emeny
{
Destroy(col.gameObject);
//消滅碰撞的物件
}
}

29_3.jpg  

 

5. 敵人撞到子彈或飛機,同時消滅

在InvaderObject的程式描述裡

加入觸發事件

void OnTriggerEnter2D(Collider2D col) //名為col的觸發事件
{
if (col.tag == "Ship" || col.tag == "Bullet" )
//如果碰撞的標籤是Ship或Bullet
{
Destroy(col.gameObject);
//消滅碰撞的物件
Destroy(gameObject); //消滅物件本身
}
}

30.JPG    

 

最後設定飛機的標籤Ship,就大功告成囉

31.JPG  

 

到此,遊戲的基本功能都有了,只是有點單調

下一篇,會講動畫和音效,讓你的遊戲活起來!

 

前往下一篇

Unity教學 2D小遊戲製作 part 3

 

想要了解程式的觀念,請參考 初學者如何建立程式的觀念(Scratch教學)

 

參考文件:

勇者拉德小酒館 Unity-射擊遊戲系列(1/?) 玩家子彈射擊

http://jerrard-liu.blogspot.tw/2014/11/ShootingGame1.html

 

 

 

arrow
arrow

    讀樂島主 發表在 痞客邦 留言(77) 人氣()