1. 程式人生 > >Unity3D案例太空射擊(Space Shooter)流程介紹與程式碼分析(下)

Unity3D案例太空射擊(Space Shooter)流程介紹與程式碼分析(下)

這部分內容關注的是遊戲性的提升,包括音效、計分等功能的實現。 傳送門: 太空射擊(Space Shooter)流程介紹與程式碼分析(下) 11.新增音效 音效分配3種,爆炸音效、發射子彈音效和背景音效。其中爆炸音效將音訊檔案直接拖入爆炸素材中即可,如下所示。
對於背景音效檔案,我們可以拖入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中要構建累加分數的函式,並在外部進行呼叫。 其定義與累加函式如下。
    private int score;
    public void AddScore(int v)
    {
        score += v;
        scoreText.text = "Score:  " + score;
    }
即可。 分數新增完畢後,就有了一個問題,在哪個外部函式進行呼叫呢?只有在子彈擊中隕石之後才能進行加分,因此我們在DestroyByContact中的隕石爆炸處進行呼叫。
  1. 在DestroyByContact中,我們新建一個GameController物件gameController,之後通過gameController呼叫加分函式。
  2. 在void Start()中新增一個GameObject物件gameControllerObject,將Hierarchy中的GameControl的Tag設定一下,作為查詢標記,如下圖所示。
  3. 如果gameControllerObject找到GameControl的Tag,將gameControllerObject.GetComponent<GameController>()賦給gameController,此時gameController即可呼叫GameControl中的函式。
  4. 用gameController呼叫AddScore函式,完成分數的新增。
上述流程變數名相似,多理解幾遍即可,這也是一種常用的使用“Tag”呼叫函式的方法。DestroyByContact的程式碼如下。
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之後的操作 遊戲結束後的操作包括以下幾個:
  1. 隕石不再產生
  2. 顯示遊戲結束
  3. 按某個鍵重新開始遊戲。
本節主要介紹這幾個功能的實現。 在GameControl中新建一個bool值,用以判斷遊戲是否結束,並新增兩個文字用以實現遊戲結束與重新開始的提示(即2、3的操作),定義與函式實現如下。
    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作為一個初學者很容易上手的遊戲,實現起來難度不大。之後將會逐步加大難度,進行更高難度遊戲的開發學習。