iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 24
0

(本篇文章網誌版:http://shineright.blogspot.tw/2016/12/day-24.html)

音效及背景音樂可說是現代數位遊戲的靈魂。今天我將為遊戲加入音效與背景音樂。

在Unity為遊戲加入音樂非常簡單。只要為Game Object加入Audio Source Component,並把要播的音樂拉至Audio Clip欄,該Game Object就會發出聲音。然而,只有發出聲音的Game Object還不夠,在Scene中,還需要有一個含有Audio Listener Component的Game Object來接收聲音,音樂才會正常播放。在每個Scene中,Unity會自動為Main Camera加上Audio Listener Component,所以除非想以別的Game Object接收聲音,不然不必另做設定。

了解Unity引擎如何處理聲音後,首先來為遊戲加上最簡單的背景音樂。

到Start Scene新增一個Game Object,命名為「Background Music」,並為它加上Audio Source Component。把要播放的音樂拉到Audio Source Component的Audio Clip欄,並勾選Play On Awake(Game Object Awake時播放)和Loop(重複播放),進入Play Mode,背景音樂就會正常播放了。

http://ithelp.ithome.com.tw/upload/images/20161224/20103149gW2luMYi5I.png

遊戲場景的背景音樂作法也相同。但有兩個地方我想修改一下。第一,我希望按下暫停鈕,背景音樂也會跟著一起暫停。第二,我希望進入遊戲結束畫面時,可以降低背景音樂的音調(pitch),讓玩家有遊戲結束的感覺。

這兩點都可用Script輕鬆解決。但首先需把Background Music Game Object的Tag改成「Background Music」,這樣才能在Script中以FindGameObjectWithTag()輕鬆找到。

開一個新的C# Script,取名為「PauseBackgroundMusicOnCanvas.cs」:

public class PauseBackgroundMusicOnCanvas : MonoBehaviour 
{
	//儲存背景音樂的AudioSource Component
    private AudioSource bgMusicAudioSource;
    
    void OnEnable()
    {
		//在所有Game Object中找尋Background Music
        bgMusicAudioSource = GameObject.FindGameObjectWithTag ("Background Music").GetComponent<AudioSource> ();
        
		//暫停音樂
        bgMusicAudioSource.Pause ();
    }
    
    void OnDisable()
    {
		//繼續音樂
        bgMusicAudioSource.UnPause ();
    }
}

這段程式碼相當簡單。我宣告了一個AudioSource型態的變數,用以儲存背景音樂的Audio Source Component,這樣就只需呼叫一次耗費時間的GameObject.FindGameObjectWithTag()函數。

Unity的AudioSource內建Pause()UnPause()函數,所以其實根本不用多寫什麼複雜程式碼就可以讓音樂暫停了。

把這段Script加到Pause Canvas的Prefab上,之後遊戲暫停時,背景音樂也會跟著暫停了。

接著,再建立一段更簡單的Script。

public class ChangeBackgroundMusicPitchOnStart : MonoBehaviour 
{
    public float pitch; //寫改成的pitch值
    
    void Start()
    {
		//取得背景音樂
        AudioSource source = GameObject.FindGameObjectWithTag ("Background Music").GetComponent<AudioSource> ();
		source.Stop();  //暫停音樂
		source.pitch = pitch;  //改變pitch
		source.Play();  //開始音樂
    }
}

把這段Script加到Game Over Canvas的Prefab上,並設定好要改成的pitch值(大約0.5~0.7之間效果不錯,正常值為1)。進入遊戲結束畫面時,背景音樂就變得低沉且緩慢了。

搞定背景音樂後,來為遊戲加入音效吧!

音效比背景音樂還複雜一些。最直覺的做法是,把所有需要音效的Game Object都加上Audio Source Component,並勾選Play On Awake,如此該Game Object產生時就會自動發出聲音了。然而,這種做法有個致命的缺點,那就是Audio Source Component和其他Component一樣,會和擁有它們的Game Object共存亡。

舉個例子,如果把Audio Source Component加在子彈上,當主角的子彈發射時,就會發出聲音。但是,如果子彈在聲音還沒播完成就碰觸到敵子彈或敵人,音效就會隨著Game Object一起被移除,以致於播出的音效只有一半。

於是,我習慣把所有音效都包裝在一個空的Game Object Prefab內,並修改每一段要發出音效的Script,增加一行Instantiate聲音Prefab的程式碼。此外,這個擁有音效的Game Object還得加上Destroy After Seconds (Script) Component,不然時間一久,Scene上就會聚集一堆空的Game Object。

這篇文章我只示範發射子彈的音效,因為其他音效的做法一模一樣。

在Scene中新增一個Game Object,命名為「Blue Ball Audio」,並為它新增Audio Source和Destroy After Seconds (Script) Component。指定好Audio Clip、調好Volume和幾秒後要Destroy後,便可把這個Game Object拉到Project欄做成Prefab。

完成音效Prefab後,到SpawnBullet.cs增加一行變數宣告:

public GameObject shootAudio = null;

以及在GameObject bullet = (Instantiate(…) as GameObject);這行產生子彈的下方加入產生音效的程式碼:

if (shootAudio != null)
    Instantiate (shootAudio, Vector2.zero, Quaternion.identity);

因為不是每個武器射子彈都有聲音,所以我先檢查有沒有shootAudio,如果有的話(shootAudio != null),才產生音效。

回到裝備的Prefab,把剛做好的音效Prefab拉到Shoot Audio欄,射子彈的音效就完成了!

待續。


上一篇
Day 23: 遊戲背景
下一篇
Day 25: 隨高度增加調整難度
系列文
我要和天一樣高!!!(Unity 2D手機小遊戲開發日誌)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言