Unity官方實例教程 Space Shooter(五)

Space Shooter 太空射擊

傳送門

Unity官方實例教程 Space Shooter(一)
Unity官方實例教程 Space Shooter(二)
Unity官方實例教程 Space Shooter(三)
Unity官方實例教程 Space Shooter(四)
Unity官方實例教程 Space Shooter(五)

前言

游戲截圖

Unity官方實例教程 Space Shooter(四)中,我們學會了:

  • 如何讓障礙向下移動
  • 如何隨機生成障礙
  • 如何生成無盡波數(shù)的障礙
  • 如何回收爆炸效果

從現(xiàn)在的游戲功能來看,我們已經(jīng)具備了基本的玩法了,但是總覺得少了什么,少了什么呢?游戲是無聲的,這樣怎么能夠體現(xiàn)我們太空射擊的激烈呢?所以我們接下來給我游戲添加一些驚心動魄的音樂,讓玩家一開始就能感受到宇宙的宏偉氣勢!

你將學到什么?

  • 如何添加游戲背景音樂
  • 如何添加游戲音效
  • 如何調(diào)整各個音效之間的平衡
  • 如何給飛船擊碎障礙后進行計分
  • 如何判斷游戲結(jié)束
  • 如何重新開始游戲
  • 如何發(fā)布游戲

一、添加背景音樂

在Unity中,要添加背景音樂其實是一件很簡單的事情,我們只需要將我們的音頻文件掛載一個GameObject上,然后做一些設置就可以讓其播放了,對于游戲的背景音樂,我們可以新建一個空的GameObject來進行掛載,但是在本例中,我們直接將音樂掛載在GameController對象上面是非常合適的,所以我們直接來試試看,首先我們在Assets->Audio文件夾中找到我們的背景音樂music_background,然后將其直接拖入GameController對象

將背景音樂拖入**GameController**

然后我們再選中GameController對象,便可以在Inspector視窗中看到音頻相關的組件了,如下圖:

音頻組件

其中我們需要關注的兩個設置:

  • Play On Awake:這個勾選后,就意味著GameObject對象一生成,音效文件就會開始播放
  • Loop:這個勾選后,就意味這音效文件會循環(huán)播放

對于我們的背景音樂,這兩個選項我們都有確保勾選,做完這些,我運行游戲便可以聽到宏偉的背景音樂了!

二、添加游戲音效

添加游戲音效的方法和添加游戲背景音樂的方法很類似,在本例中我們會添加3個音效

  • 障礙爆炸音效
  • 飛船爆炸音效
  • 子彈射擊音效

首先我們來看前面2個爆炸音效,這兩個音效實現(xiàn)非常簡單,我們找到爆炸效果的Prefab文件,然后直接將音效文件拖入Prefab中,在這邊,我們?yōu)榱朔奖阃蟿樱瑢?strong>Project視圖改為One Column Layout模式

One Column Layout模式

然后在Assets->Audio文件夾中找到對應的兩個音效文件explosion_asteroidexplosion_player,并分別將兩個音效文件拖入explosion_asteroidexplosion_player兩個Prefab

拖入音效文件

然后確保Play On Awake模式是勾選的,做完這些,運行一下游戲,便可聽到爆炸的音效了

還剩下一個子彈設計的音效,他的掛載方式和上面的都一樣,只是播放的方式是需要在代碼中激活的,我們首先在Assets->Audio文件夾中找到射擊音效weapon_player,然后將音效文件拖入Player對象

拖入**Player**對象

然后去掉Play On Awake的勾選,因為我們不能在游戲一開始就播放射擊音效,我們需要在發(fā)射子彈的時候才會播放,所以我們打開PlayerController腳本,進行編輯:

完整的代碼
  • 我們在射擊功能的代碼中,增加紅線標記的語句,這個是5.2的新寫法,簡單來說就是獲取對象的AudioSource組件來調(diào)用播放功能

寫完代碼,保存一下,然后回到Unity編輯器,運行游戲,發(fā)射子彈時便可以可以聽到子彈射擊音效了

三、調(diào)節(jié)音效平衡

現(xiàn)在我們有了背景音樂,爆炸音效和子彈射擊的音效,如果耳朵敏感的朋友,可能會覺得,相對于爆炸音效,子彈射擊的音效有些過于大了,所以我們可以通過單獨調(diào)節(jié)射擊音效的音量,來到達各個音效之間的一個平衡,首先我們選中Player對象,然后在其AudioSource組件中調(diào)整Volume選項,在本例中,我們將Volume調(diào)節(jié)為0.5

調(diào)整射擊音效的音量

然后我們在運行一下,現(xiàn)在各個音效就處于一個比較平衡的狀態(tài)了

四、給游戲計分

現(xiàn)在我們的游戲有了玩法,有了聲音,已經(jīng)可以玩樂了,如果增加一個計分功能,就能讓玩家有更好的追求,也讓重復的射擊動作變得有意義,要實現(xiàn)計分功能,我們首先需要一個UI來顯示分數(shù),下面我們就來創(chuàng)建一個計分UI,首先我們新建一個Text類型的GameObject,然后將其命名為Score Text,在5.2版本中,新建一個UI類的GameObject,編輯器會自動幫我們創(chuàng)建CanvasEventSystem兩個GameObject

截圖

為了讓我們的UI適配我們設定的尺寸,所以我需要選中Canvas來修改UI縮放模式,在本例中,我們使用Scale With Screen Size模式,也就根據(jù)屏幕尺寸來縮放,然后將引用的屏幕分辨率設置為600*900,也就是我們的游戲屏幕尺寸

UI縮放模式

然后選中Score Text,修改它的位置,使其處于屏幕合適的位置,在本例中,我們將它的x和y值分別設置為-205和420,讓其處于屏幕的左上角

左上角的計分UI

有了這個計分UI后,我們需要思考一下,如何才能讓它正確顯示玩家的分數(shù)呢?

  • 首先我們得有一個變量來記錄玩家的分數(shù)
  • 然后我們需要有一個方法,來實現(xiàn)當分數(shù)發(fā)生變化是通知UI更新分數(shù)
  • 接著我們需要在障礙被子彈擊碎時增加一定分數(shù)

那么我們就來看看如何實現(xiàn)上面的內(nèi)容,要實現(xiàn)上面內(nèi)容的第一點和第二點,比較合理的方式是在我的GameController里面來實現(xiàn),所以我們打開GameController腳本,增加以下代碼:

完整的代碼
  • 首先我們引入了UnityEngine.UI的庫文件,因為我們下面會需要在代碼中定義Text類型的變量,而Text類型的變量屬于UnityEngine.UI的內(nèi)容,所以我們需要在開頭進行引入,這樣程序才能識別Text類型的變量
  • 然后我們定義了一個私有變量score,來記錄玩家的分數(shù),因為我們不希望這個變量可以手動設置,所以設置為私有類型的
  • 接著我們定義一個公共變量scoreText,用來設置顯示分數(shù)的UI對象
  • 然后我們在游戲開始時,將score設置為0,接著調(diào)用UpdateScore方法來更新分數(shù)UI
  • 接著我們來看看UpdateScore方法的具體內(nèi)容,非常簡單,就是修改scoreText的文本內(nèi)容,文本內(nèi)容由兩部分組成,Score:固定文字加上score變量數(shù)值
  • 最后我們定義一個公共的方法addScore,之所以是公共的,因為我會在其他的腳本中調(diào)用,所以需要將其設置為public類型,函數(shù)里面我們就只有兩句話,將現(xiàn)在的分數(shù)加上增加的分數(shù),然后再更新分數(shù)

寫完代碼,保存一下,然后回到Unity編輯器,將我們的Score Text對象拖入到scoreText變量中

拖入到**scoreText**變量

做完這些,我們就實現(xiàn)了第一點和第二點的內(nèi)容了,那么第三點我們該如何實現(xiàn)呢?我怎么實現(xiàn)子彈擊碎障礙的時候來增加分數(shù)呢?我們先回憶一下,子彈擊碎障礙的邏輯代碼在哪個腳本里面?沒錯就是DestroyByContact,所以打開它然后新增以下代碼:

完整的代碼
  • 首先我們定義一個公共變量score,來設置每個障礙的擊碎后的得分
  • 然后我定義一個私有變量gameController,因為我們需要通過調(diào)用GameController腳本中的addScore方法來增加分數(shù)
  • 接著我們在Start方法中,需要獲取GameController的實例,這里我們的步驟是,首先找到GameController的GameObject,然后在通過GetComponent方法來獲取GameController腳本的實例
  • 這里面有兩個if語句,第一個if是表示當我們獲取的GameController對象不為空時,我才通過GetComponent方法來獲取GameController腳本的實例
  • 第二個if是表示當我們獲取的GameController對象是空的時候,我們輸出Debug信息,告訴我們腳本沒有找到
  • 最后我們在障礙被擊碎的邏輯里面,調(diào)用GameControlleraddScore方法來增加分數(shù)

寫完代碼,保存一下,然后回到Unity編輯器,將score設置為10(這個數(shù)值你可以根據(jù)自己喜好來設置,但建議最好大于0),然后運行游戲,這時你會發(fā)現(xiàn)每次你擊碎障礙后,分數(shù)就會增加10分

五、是時候結(jié)束游戲啦

現(xiàn)在我們的游戲越發(fā)完美了,但是還存在一個挺嚴重的問題,就是游戲無法結(jié)束,即使我們的飛船被炸毀,游戲也不會結(jié)束,這可不太好,所以我們需要設置一下,當我們的飛船被炸毀后,我們就結(jié)束游戲!

相信有些聰明的朋友,已經(jīng)想到了制作思路——我們在判斷飛船炸毀的腳本里面,添加一句讓游戲結(jié)束的代碼就行了,沒錯,其實思路就是這么簡單,接下來我們來看看怎么實現(xiàn):

添加GameOver的UI

首先我們還是新建一個Text對象,然后命名為GameOver Text,然后修改它的顯示內(nèi)容為GameOver,為了讓他更加醒目,我們將他的字體調(diào)整為25,然后位置擺放在屏幕的中間,并且修改它的文本對象方式為中心對象,接著將其字體顏色設置為紅色,具體屬性設置如下圖:

GameOver的屬性設置

然后你變會看到游戲屏幕中間就會有一個大大的紅色的GameOver了,接著我們需要修改GameController腳本來讓程序知道如何判斷游戲結(jié)束

完整的代碼
  • 首先我們定義一個公共變量gameOverText,用來設置顯示GameOver的UI對象
  • 然后我們定義一個私有的變量,用來保存游戲是否結(jié)束的標志,它是Bool類型的變量,只有true和false兩種情況
  • 接著我們在游戲開始,將gameOverText的文字內(nèi)容設置為空,因為一開始游戲肯定還沒有結(jié)束,所以我們不能讓玩家看到gameOverText
  • 同時一開始我們也需要將gameOver標記為false,即游戲還未結(jié)束
  • 然后我們定義一個公共方法GameOver,來實現(xiàn)游戲結(jié)束時的邏輯處理,在這個方法中,我們做了兩件事情,一是將gameOver標記為true,然后將gameOverText的文字內(nèi)容設置為“GameOver”

寫完代碼,保存一下,然后回到Unity編輯器,將我們的GameOver Text對象拖入到gameOverText變量中

拖入到**gameOverText**

接著我們再打開DestroyByContact腳本,進行如下編輯:

完整的代碼
  • 我們在飛機撞毀的邏輯中,調(diào)用GameOver方法來通知GameController來結(jié)束游戲

寫完代碼,保存一下,然后回到Unity編輯器,運行游戲,測試一下,你會發(fā)現(xiàn)當飛船被撞毀后,游戲就會出現(xiàn)GameOver的提示了

六、有結(jié)束就有重新開始

現(xiàn)在我們游戲可以結(jié)束了,但是如果游戲結(jié)束之后,我們不能重新開始,那游戲豈不是只能玩一次,所以我們需要給游戲增加重新開始的功能,為了讓玩家知道怎么來重新開始,所以我們需要新建一個Text來提示玩家如何來重新開始,我們將新建的Text命名為Restart Text,然后將其的屬性設置為下圖所示:

**Restart Text**的屬性設置

然后我們打開GameController腳本來控制重新開始的邏輯:

完整的代碼
  • 首先我們定義一個公共變量restartText,來設置顯示重新開始信息的UI對象
  • 然后我們定義一個私有變量restart,來標記游戲是否處于重新開始狀態(tài)
  • 接著我們在游戲開始的時候,將restartText的文本內(nèi)容設置為空,因為一開始不需要顯示任何信息,同時將restart標記為false
  • 然后我們在Update方法中進行檢測,如果游戲處于重新開始狀態(tài)下,并且玩家按下了R鍵,我們就重新加載當前場景(即重新開始游戲)
  • 最后我們在障礙生成的循環(huán)中,進行檢測,如果游戲處于GameOver狀態(tài),我們就將restart標記為true,同時將restartText的文本內(nèi)容設置為“Press 'R' to Restart”

寫完代碼,保存一下,回到Unity編輯器,然后將Restart Text拖入restartText,接著運行游戲,測試一下

最終效果

七、最后一步——發(fā)布游戲

終于,我們的游戲制作已經(jīng)完成了,接下來就是發(fā)布游戲,可以分享給我們的朋友玩啦,關于如何發(fā)布游戲在Unity官方實例教程 Roll-a-Ball(二)的最后我們有講解過,所以這里就不做詳細介紹啦,希望每個讀者朋友都能真正學以致用,而不是依賴教程,最后謝謝所有能夠看到這里的朋友!

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容