Unity實(shí)現(xiàn)音頻播放管理器
本文實(shí)例為大家分享了Unity實(shí)現(xiàn)音頻播放管理器的具體代碼,供大家參考,具體內(nèi)容如下
1、模塊化,直接用。創(chuàng)建一個(gè)空物體,把此腳本拖上去,然后把需要播放的所有音頻拖到面板上的”AudioList“中;
2、通過(guò)AudioManagerP._instance直接調(diào)用方法,包含:
- 暫停;
- 繼續(xù)播放;
- 停止播放;
- 播放背景音樂(lè)(0號(hào)播放器專(zhuān)用于播放背景音);
- 直接播放聲音(帶參數(shù)1、播放器序號(hào) 2、音頻的名字 3、聲音大小 4、 是否循環(huán));
- 直接播放呻吟(帶參數(shù)1、播放器序號(hào) 2、音頻的名字);
- 聲音淡入(帶參數(shù)1、播放器序號(hào) 2、音頻的名字 3、 是否循環(huán));
- 聲音淡出(帶參數(shù) 播放器序號(hào) )。
優(yōu)點(diǎn):同時(shí)可以播放很多個(gè)聲音源,可以精確控制每個(gè)播放源的狀態(tài)
缺點(diǎn):不知道。
源碼
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AudioManagerP : MonoBehaviour { public static AudioManagerP _instance;//單例 private bool isOut; private bool isIn; void Awake() { _instance = this; DontDestroyOnLoad(this); } //audioClipl列表 public List<AudioClip> audioList; //初始聲音預(yù)設(shè)數(shù)量 private int initAudioPrefabcount = 7; //記錄靜音前的音量大小 [HideInInspector] public float tempVolume = 0; //是否靜音 private bool isMute = false; public bool IsMute { set { isMute = value; if (isMute) { tempVolume = AudioListener.volume; AudioListener.volume = 0; } else { AudioListener.volume = tempVolume; } } private get { return isMute; } } //聲音大小系數(shù) private float volumeScale = 1; public float VolumeScale { set { volumeScale = Mathf.Clamp01(value); if (!IsMute) { AudioListener.volume = value; } } private get { return volumeScale; } } //audio字典 private Dictionary<string, AudioClip> audioDic = new Dictionary<string, AudioClip>(); //背景音樂(lè) private AudioSource bgAudioSource; //聲音對(duì)象池 private AudioObjectPool audioObjectPool; private void Start() { GameObject audioPrefab = new GameObject("AudioObjectPool"); audioPrefab.AddComponent<AudioSource>(); audioPrefab.GetComponent<AudioSource>().playOnAwake = false; audioObjectPool = new AudioObjectPool(audioPrefab, initAudioPrefabcount); audioPrefab.hideFlags = HideFlags.HideInHierarchy; audioPrefab.transform.SetParent(this.transform); foreach (AudioClip ac in audioList) { audioDic.Add(ac.name, ac); } bgAudioSource = this.transform.GetChild(0).GetComponent<AudioSource>(); } private void Update() { //測(cè)試代碼 if (Input.GetMouseButtonDown(0)) { //StartCoroutine(AudioFadeIn(0, "沈木-Sold Out(熱播版)", true)); //音樂(lè)漸入 //PlayAudio(0, "沈木-Sold Out(熱播版)"); //直接播放 } if (Input.GetMouseButtonDown(1)) { //StartCoroutine(AudioFadedOut(0)); //音樂(lè)淡出 } } /// <summary> /// 音頻播放 /// </summary> /// <param name="index">播放器序號(hào)(用第幾個(gè)AudioSource播放)</param> public void PauseAudio(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); audioSource.Pause(); } /// <summary> /// 繼續(xù)播放 /// </summary> /// <param name="index">播放器序號(hào)</param> public void ResumeAudio(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); audioSource.UnPause(); } /// <summary> /// 停止播放聲音 /// </summary> /// <param name="index">播放器序號(hào)</param> public void StopAudio(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); audioSource.Stop(); } /// <summary> /// 播放背景音樂(lè),這里直接固定0號(hào)播放器用來(lái)播放北京音樂(lè) /// </summary> /// <param name="audioNme"></param> public void PlayBGMAudio(string audioNme) { AudioClip audioClip; if (audioDic.TryGetValue(audioNme, out audioClip)) { bgAudioSource.gameObject.SetActive(true); bgAudioSource.clip = audioClip; this.transform.GetChild(0).gameObject.SetActive(true); bgAudioSource.Play(); bgAudioSource.loop = true; } } /// <summary> /// 直接播放聲音 /// </summary> /// <param name="index">播放器序號(hào)</param> /// <param name="audioName">音頻文件名稱(chēng)</param> /// <param name="volume">音量大小</param> /// <param name="isLoop">是否循環(huán)</param> public void PlayAudio(int index, string audioName, float volume = 1, bool isLoop = false) { //Debug.Log("------------執(zhí)行播放聲音----------------"); AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (IsMute || audioSource == null) { return; } StopAllCoroutines(); AudioClip audioClip; if (audioDic.TryGetValue(audioName, out audioClip)) { //Debug.Log("按鈕點(diǎn)擊的clip名字是:"+audioClip.name); audioSource.gameObject.SetActive(true); audioSource.loop = isLoop; audioSource.clip = audioClip; audioSource.volume = volume; if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.Play(); } } /// <summary> /// 重載播放,只有播放器和音頻 /// </summary> /// <param name="index">播放器序號(hào)</param> /// <param name="audioName">音頻的名稱(chēng)</param> public void PlayAudio(int index, string audioName) { //Debug.Log("------------執(zhí)行播放聲音----------------"); AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (IsMute || audioSource == null) { return; } StopAllCoroutines(); AudioClip audioClip; if (audioDic.TryGetValue(audioName, out audioClip)) { //Debug.Log("按鈕點(diǎn)擊的clip名字是:"+audioClip.name); audioSource.gameObject.SetActive(true); audioSource.clip = audioClip; if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.Play(); } } /// <summary> /// 聲音淡入 /// </summary> /// <param name="index">播放器序號(hào)</param> /// <param name="audioName">音頻名稱(chēng)</param> /// <param name="isLoop">是否循環(huán)</param> /// <returns></returns> public IEnumerator AudioFadeIn(int index, string audioName, bool isLoop) { float initVolume = 0; float preTime = 1.0f / 5; //漸變率 AudioClip audioClip; if (audioDic.TryGetValue(audioName, out audioClip)) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (audioSource == null) yield break; audioSource.gameObject.SetActive(true); //聲音播放對(duì)象默認(rèn)為false,播放時(shí)把對(duì)應(yīng)的對(duì)象設(shè)為true audioSource.clip = audioClip; audioSource.volume = 0; audioSource.loop = isLoop; print("zhi 0"); if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.Play(); audioSource.volume = 0; while (true) { initVolume += 1 * Time.deltaTime * preTime; //聲音漸高 audioSource.volume = initVolume; //將漸高變量賦值給播放器音量 if (initVolume >= 1 - 0.02f) //如果很接近配置文件中的值,那么將其固定在配置文件中的值(最大值) { audioSource.volume = 1; break; } yield return 1; } } } /// <summary> /// 聲音淡出 /// </summary> /// <param name="index">淡出的播放器序號(hào)</param> /// <returns></returns> public IEnumerator AudioFadedOut(int index) { AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>(); if (audioSource == null || audioSource.volume == 0 || audioSource == null) { yield break; } float initVolume = audioSource.volume; float preTime = 1.0f / 5; while (true) { initVolume += -1 * Time.deltaTime * preTime; audioSource.volume = initVolume; if (initVolume <= 0) { audioSource.volume = 0; audioSource.Stop(); break; } yield return 1; } } /// <summary> /// 初始化音頻 /// </summary> /// <param name="audioSource"></param> private void InitAudioSource(AudioSource audioSource) { if (audioSource == null) { return; } if (audioSource.isPlaying) { audioSource.Stop(); } audioSource.playOnAwake = false; audioSource.loop = false; audioSource.volume = 1; audioSource.clip = null; audioSource.name = "AudioObjectPool"; } private void Destroy() { StopAllCoroutines(); } } #region 聲音對(duì)象池 /*聲音對(duì)象池,待完善,可能存在同一時(shí)間多種聲音源在播放,硬切或者播放完畢再切,無(wú)法判定是那種,無(wú)法準(zhǔn)確釋放AudioObjectPool 這里只是在開(kāi)局使用對(duì)象池生成了指定個(gè)數(shù)的播放器,沒(méi)有用到獲取和釋放播放器對(duì)象*/ public class AudioObjectPool { //要生成的對(duì)象池預(yù)設(shè) private GameObject prefab; //對(duì)象池列表 private List<GameObject> pool; //構(gòu)造函數(shù) public AudioObjectPool(GameObject prefab, int initialSize) { this.prefab = prefab; this.pool = new List<GameObject>(); for (int i = 0; i < initialSize; i++) { //進(jìn)行初始化 AllLocateInstance(); } } //獲取實(shí)例 public GameObject GetInstance() { if (pool.Count == 0) { //創(chuàng)建實(shí)例 } GameObject instance = pool[0]; pool.RemoveAt(0); instance.SetActive(true); return instance; } //釋放實(shí)力 public void ReleaseInstance(GameObject instance) { instance.SetActive(false); pool.Add(instance); } //生成本地實(shí)力 private GameObject AllLocateInstance() { GameObject instance = (GameObject)GameObject.Instantiate(prefab); instance.transform.SetParent(AudioManagerP._instance.transform); instance.SetActive(false); pool.Add(instance); return instance; } } #endregion
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# 調(diào)用API函數(shù)彈出映射網(wǎng)絡(luò)驅(qū)動(dòng)器對(duì)話框問(wèn)題
C#中的.net的常用對(duì)話框中沒(méi)有映射網(wǎng)絡(luò)驅(qū)動(dòng)映射對(duì)話框,所以需要用windows的API函數(shù)去實(shí)現(xiàn)彈出映射網(wǎng)絡(luò)驅(qū)動(dòng)器對(duì)話框2014-01-01C#實(shí)現(xiàn)托盤(pán)程序并禁止多個(gè)應(yīng)用實(shí)例運(yùn)行的方法
這篇文章主要介紹了C#實(shí)現(xiàn)托盤(pán)程序并禁止多個(gè)應(yīng)用實(shí)例運(yùn)行的方法,涉及C#中NotifyIcon控件的使用及設(shè)置標(biāo)志位控制程序只運(yùn)行一個(gè)的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11C#實(shí)現(xiàn)帶行數(shù)和標(biāo)尺的RichTextBox
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)帶行數(shù)和標(biāo)尺的RichTextBox,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12C# 解決在Dictionary中使用枚舉的效率問(wèn)題
這篇文章主要介紹了C# 解決在Dictionary中使用枚舉的效率問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04c#語(yǔ)言使用Unity粒子系統(tǒng)制作手雷爆炸
這篇文章主要為大家介紹了Unity的粒子系統(tǒng)由粒子發(fā)射器、粒子動(dòng)畫(huà)器、粒子渲染器組成,通過(guò)使用一或兩個(gè)紋理多次繪制,創(chuàng)造一個(gè)混沌的效果,通過(guò)復(fù)習(xí)粒子系統(tǒng)做一個(gè)手雷和實(shí)彈投擲現(xiàn)場(chǎng)2022-04-04linux操作系統(tǒng)安裝MONO執(zhí)行C#程序的詳解步驟
這篇文章主要介紹了linux操作系統(tǒng)安裝MONO執(zhí)行C#程序詳解步驟,有需要的可以參考一下2013-12-12C#傳值方式實(shí)現(xiàn)不同程序窗體間通信實(shí)例
Form2構(gòu)造函數(shù)中接收一個(gè)string類(lèi)型參數(shù),即Form1中選中行的文本,將Form2的TextBox控件的Text設(shè)置為該string,即完成了Form1向Form2的傳值2013-12-12