Unity3D案例太空射擊(Space Shooter)流程介紹與程式碼分析(下)
阿新 • • 發佈:2019-01-22
這部分內容關注的是遊戲性的提升,包括音效、計分等功能的實現。
傳送門:
太空射擊(Space Shooter)流程介紹與程式碼分析(下)
11.新增音效
音效分配3種,爆炸音效、發射子彈音效和背景音效。其中爆炸音效將音訊檔案直接拖入爆炸素材中即可,如下所示。
對於背景音效檔案,我們可以拖入GameController,並勾選loop,這樣在遊戲開始時即可自動迴圈播放。
而發射子彈的音效,在PlayerControl中實現,開啟程式碼檔案。新增定義和實現程式碼
此時,需向Playership中新增一個AudioSource,否則會報錯。 12.銷燬爆炸效果及計分功能 在之前的進度中,我們實現了大部分遊戲功能,但是無法消除爆炸效果,如下所示。
本部分就介紹如何解決這一問題。 新建一個指令碼,DestroyExplosion,寫入
分數顯示: 在4.6.9中不能像教程那樣新增GUIText,因此使用一個替代的Text,來代替。GameObject——>UI——>Text新增即可。GUIText的定義與Text差不多。 例如:public GUIText scoreText 與public Text ScoreText對應即可,呼叫函式等操作方法是一樣的。
在GameController中要構建累加分數的函式,並在外部進行呼叫。 其定義與累加函式如下。
對於背景音效檔案,我們可以拖入GameController,並勾選loop,這樣在遊戲開始時即可自動迴圈播放。
而發射子彈的音效,在PlayerControl中實現,開啟程式碼檔案。新增定義和實現程式碼
即可,之後將音效拖入其中即可實現。public AudioClip weaponFire; //新增音效 void Update() { if (Input.GetKeyDown(KeyCode.Space) &&Time.time > nextFireTime) if (Input.GetButton ("Fire1")&&Time.time > nextFireTime) { audio.PlayOneShot(weaponFire); //播放音效 nextFireTime = Time.time + fireRate; Instantiate //shooting function ( bullet, bulletPosition.transform.position, bulletPosition.transform.rotation ); } } }
此時,需向Playership中新增一個AudioSource,否則會報錯。 12.銷燬爆炸效果及計分功能 在之前的進度中,我們實現了大部分遊戲功能,但是無法消除爆炸效果,如下所示。
本部分就介紹如何解決這一問題。 新建一個指令碼,DestroyExplosion,寫入
即可 之後將這一指令碼拖入各個爆炸效果中,如下所示即可。using UnityEngine; using System.Collections; public class DestroyExplosion : MonoBehaviour { public float lifetime; void Start () { Destroy (this.gameObject, lifetime); } }
分數顯示: 在4.6.9中不能像教程那樣新增GUIText,因此使用一個替代的Text,來代替。GameObject——>UI——>Text新增即可。GUIText的定義與Text差不多。 例如:public GUIText scoreText 與public Text ScoreText對應即可,呼叫函式等操作方法是一樣的。
在GameController中要構建累加分數的函式,並在外部進行呼叫。 其定義與累加函式如下。
即可。 分數新增完畢後,就有了一個問題,在哪個外部函式進行呼叫呢?只有在子彈擊中隕石之後才能進行加分,因此我們在DestroyByContact中的隕石爆炸處進行呼叫。private int score; public void AddScore(int v) { score += v; scoreText.text = "Score: " + score; }
- 在DestroyByContact中,我們新建一個GameController物件gameController,之後通過gameController呼叫加分函式。
- 在void Start()中新增一個GameObject物件gameControllerObject,將Hierarchy中的GameControl的Tag設定一下,作為查詢標記,如下圖所示。
- 如果gameControllerObject找到GameControl的Tag,將gameControllerObject.GetComponent<GameController>()賦給gameController,此時gameController即可呼叫GameControl中的函式。
- 用gameController呼叫AddScore函式,完成分數的新增。
using UnityEngine;
using System.Collections;
public class DestroyByCotact : MonoBehaviour {
public GameObject explosion;
public GameObject playerExplosion;
private GameController gameController; //步驟1,新建GameController物件
public int score = 10;
void Start()
{
GameObject gameControllerObject = GameObject.FindWithTag ("GameController"); //步驟2,查詢GameControl
if (gameControllerObject != null)
{
gameController = gameControllerObject.GetComponent<GameController>(); //步驟3,若步驟2查詢到,賦值給gameController
}
if (gameControllerObject == null)
{
Debug.Log("could not find the gamecontroller");
}
}
void OnTriggerEnter (Collider other)
{
if (other.gameObject.tag == "Boundary") //if other.gameObject belongs to "Boundary",do nothing.
{
return;
}
if (other.gameObject.tag == "Player") //if other.gameObject belongs to "Player",destroy the playership.
{
Instantiate (playerExplosion, this.transform.position, this.transform.rotation);
gameController.GameOver();
}
Destroy (other.gameObject);
gameController.AddScore (score); //步驟4,進行加分
Destroy (this.gameObject);
Instantiate (explosion, this.transform.position, this.transform.rotation); //destroy the asteriod
}
}
13.GameOver之後的操作
遊戲結束後的操作包括以下幾個:
- 隕石不再產生
- 顯示遊戲結束
- 按某個鍵重新開始遊戲。
private bool gameOver = false;
public void GameOver()
{
gameOver = true;
gameOverText.text = "Game Over!";
helpText.text = "Press 'R' to Restart";
}
之後實現隕石不再產生的操作(即1),在產生隕石函式中新增判斷語句並break,如下
IEnumerator SpawnWave()
{
yield return new WaitForSeconds(gameStartTime);
while (true)
{
for (int i=0; i<10; i++)
{
Spawn ();
yield return new WaitForSeconds (waitTime);
}
yield return new WaitForSeconds(waveTime);
if(gameOver) break; //若結束,則break
}
}
函式定義實現後,需要確定何時呼叫GameOver,我們可以在DestroyByContact中的飛機爆炸中進行呼叫。程式碼如下
if (other.gameObject.tag == "Player")
{
Instantiate (playerExplosion, this.transform.position, this.transform.rotation);
gameController.GameOver(); //12節已經建立了Tag的關係,因此 gameController可以直接呼叫GameContrl中的GameOver函式
}
對於重新開始遊戲,我們可以在GameControl中用Update函式進行實現,程式碼如下
void Update () {
if (gameOver && Input.GetKeyDown (KeyCode.R))
{
Application.LoadLevel(Application.loadedLevel); //重新載入遊戲函式
}
至此,所有的函式功能都以實現,遊戲已經可以正常執行。
總結:Space Shooter作為一個初學者很容易上手的遊戲,實現起來難度不大。之後將會逐步加大難度,進行更高難度遊戲的開發學習。