對於Unity3D的音樂音效這塊一直沒有好好的看過,現在准備好好的研究一下,並作為一個筆記記錄下。
支持格式
在游戲中,一般存在兩種音樂,一種是時間較長的背景音樂,一種是時間較短的音效(比如按鈕點擊,開槍音效等)。
Unity3D支持下面幾種音樂格式:
- AIFF:適用於較短的音樂文件可用作游戲打斗音效
- WAV:適用於較短的音樂文件可用作游戲打斗音效
- MP3:適用於較長的音樂文件可用作游戲背景音樂
- OGG:適用於較長的音樂文件可用作游戲背景音樂
音樂組件
Unity3D中對音樂進行了封裝,總體來說,要播放音樂需要3個基本的組件,下面我們來看看這3個組件。
AudioListener
一般我們創建場景時在主Camera上就會帶有這個組件,該組件只有一個功能,就是監聽當前場景下的所有音效的播放並將這些音效輸出,如果沒有這個組件,則不會發出任何的聲音。好消息是,我們不需要創建多個該組件,一般場景中只需要在任意的GameObject上添加一個該組件就可以了,但是要保證這個GameObject不被銷毀,所以一般按照Unity的做法,在主攝像機中添加即可。
AudioSource
控制一個指定音樂播放的組件,可以通過屬性設置來控制音樂的一些效果,可以查看官方的文檔:http://docs.unity3d.com/Manual/class-AudioSource.html。
下面列出一些常用的屬性:
- AudioClip:聲音片段,還可以在代碼中去動態的截取音樂文件。
- Mute:是否靜音。
- Bypass Effects:是否打開音頻特效。
- Play On Awake:開機自動播放。
- Loop:循環播放。
- Volume:聲音大小,取值范圍0.0 到 1.0。
- Pitch:播放速度,取值范圍在 -3 到 3 之間 設置1 為正常播放,小於1 為減慢播放 大於1為加速播放。
AudioClip
當我們把一個音樂導入到Unity3D中,這個音樂文件就會變成一個AudioClip對象,即我們可以直接將其拖拽到AudioSource的AudioClip屬性中,也可以通過Resources或AssetBundle進行加載,加載出來的對象類型就是AudioClip。
看例子
播放音樂的簡單例子
這個例子我們直接通過簡單的拖拽的點擊不寫一行代碼實現音樂的播放。
新建一個場景,給Main Camera添加一個Audio Source組件,並將我們的音樂文件拖拽到Audio Clip屬性上,勾選Loop使其可以進行循環播放。
運行程序就可以聽到聲音了。
3D音效效果
Unity為啥要把音樂播放拆分成這3個組件呢?當然是有原因的,個人認為其中最重要的就是實現3D音效效果。
如果我們將Audio Listener看作一雙耳朵的話就可以很好的理解什么是3D音效效果了,Unity會根據Audio Listener對象所在的GameObject和Audio Source所在的GameObject判斷一下距離和位置來模擬真實世界中的音量近大遠小的效果。
首先,找到我們導入的音樂文件,必須設置為3D音樂,默認就是。當然如果是2D的音樂就不會有近大遠小的效果了。
我們新建一個場景,添加3個GameObject,給第一個添加一個Audio Listener組件,其它兩個添加Audio Source組件並賦予兩個音樂文件。
移除Main Camera上的Audio Listener組件,按照下面的位置擺放一下這3個組件。
運行游戲,返回Scene視窗,拖拽Audio Listener組件的位置,就可以感受到好比在兩個音響之間移動的效果了。
(對於每個Audio Source聲音可傳遞的距離可以通過拖拽其球形的線條進行調整。)
Resources加載
這里我們看看通過代碼如何實現音樂的控制和播放。
我們把我們的音樂文件放到Resources文件夾中,新建一個場景和一個GameObject,並將下面的腳本添加到這個GameObject上即可:
1 using UnityEngine; 2 3 public class ResourcesDemo : MonoBehaviour 4 { 5 private AudioSource _audioSource; 6 7 void Start() 8 { 9 //添加 Audio Source 組件 10 _audioSource = this.gameObject.AddComponent<AudioSource>(); 11 12 //加載 Audio Clip 對象 13 AudioClip audioClip = Resources.Load<AudioClip>("bgm"); 14 15 //播放 16 _audioSource.loop = true; 17 _audioSource.clip = audioClip; 18 _audioSource.Play(); 19 } 20 }
運行就可以聽到聲音了。
AssetBundle加載
音樂在AssetBundle中又該如何控制和播放呢?
首先我們需要通過腳本對文件進行打包。
1 using UnityEditor; 2 using UnityEngine; 3 4 public class AssetBundleCreator 5 { 6 [MenuItem("Demo/CreateAssetBundle")] 7 private static void CreateAssetBundle() 8 { 9 BuildPipeline.BuildAssetBundle(null, new [] 10 { 11 AssetDatabase.LoadMainAssetAtPath("Assets/Audio/bgm.ogg"), 12 AssetDatabase.LoadMainAssetAtPath("Assets/Audio/sound.ogg") 13 }, 14 Application.streamingAssetsPath + "/Audio.assetbundle", 15 BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.UncompressedAssetBundle, 16 BuildTarget.StandaloneWindows64); 17 } 18 }
接下來新建一個場景和一個GameObject,並將下面的腳本添加到這個GameObject上即可:
1 using UnityEngine; 2 3 public class AssetBundleDemo : MonoBehaviour 4 { 5 private AudioSource _audioSource; 6 7 void Start() 8 { 9 AssetBundle assetBundle = AssetBundle.CreateFromFile(Application.streamingAssetsPath + "/Audio.assetbundle"); 10 11 //添加 Audio Source 組件 12 _audioSource = this.gameObject.AddComponent<AudioSource>(); 13 14 //加載 Audio Clip 對象 15 AudioClip audioClip = assetBundle.Load("sound", typeof(AudioClip)) as AudioClip; 16 17 //播放 18 _audioSource.loop = true; 19 _audioSource.clip = audioClip; 20 _audioSource.Play(); 21 } 22 }
Play和PlayOneShot的區別
AudioSource播放聲音提供了兩種方法,分別如下:
public void Play(ulong delay = 0);
public void PlayOneShot(AudioClip clip, float volumeScale = 1.0F);
那么這兩個方法有啥區別呢,或者說在什么樣的情況下應該使用哪個方法呢?
我們先看看Play方法,該方法可以和其它方法配合使用,比如Pause(暫停)和Stop(停止),播放的是clip屬性對應的Audio Clip對象,同一時刻只會有一個clip音樂進行播放。如果要同時使用Play方法播放兩個音樂就需要再添加一個Audio Source對象了。
而PlayOneShot是指馬上播放一個音樂且只播放一次,同時Pause和Stop對其無效,如果我們調用該方法播放多次音樂,則多個音樂會同時被播放出來。
使用場景
Play方法適合播放背景音樂,因為背景音樂同一時刻只會有一個再播放,而且還需要可以控制其播放和暫停等。
PlayOneShot方法適合播放音效,因為音效一般只會播放一次且不需要其它的控制,同時多個音效播放時是可以共存的,即可以聽到多個聲音。