Unity實(shí)現(xiàn)音頻播放管理器
本文實(shí)例為大家分享了Unity實(shí)現(xiàn)音頻播放管理器的具體代碼,供大家參考,具體內(nèi)容如下
1、模塊化,直接用。創(chuàng)建一個(gè)空物體,把此腳本拖上去,然后把需要播放的所有音頻拖到面板上的”AudioList“中;
2、通過AudioManagerP._instance直接調(diào)用方法,包含:
- 暫停;
- 繼續(xù)播放;
- 停止播放;
- 播放背景音樂(0號(hào)播放器專用于播放背景音);
- 直接播放聲音(帶參數(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>();
//背景音樂
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)); //音樂漸入
//PlayAudio(0, "沈木-Sold Out(熱播版)"); //直接播放
}
if (Input.GetMouseButtonDown(1))
{
//StartCoroutine(AudioFadedOut(0)); //音樂淡出
}
}
/// <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>
/// 播放背景音樂,這里直接固定0號(hào)播放器用來播放北京音樂
/// </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">音頻文件名稱</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">音頻的名稱</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">音頻名稱</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í)間多種聲音源在播放,硬切或者播放完畢再切,無法判定是那種,無法準(zhǔn)確釋放AudioObjectPool
這里只是在開局使用對(duì)象池生成了指定個(gè)數(shù)的播放器,沒有用到獲取和釋放播放器對(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# 數(shù)據(jù)驗(yàn)證Regex示例詳解
文章介紹了C#中使用Regex進(jìn)行數(shù)據(jù)驗(yàn)證的方法,包括整數(shù)和小數(shù)的正負(fù)驗(yàn)證,以及郵箱和身份證號(hào)的格式驗(yàn)證,感興趣的朋友一起看看吧2025-02-02
C#創(chuàng)建Windows Service(Windows 服務(wù))的方法步驟
本文介紹了如何用C#創(chuàng)建、安裝、啟動(dòng)、監(jiān)控、卸載簡(jiǎn)單的Windows Service 的內(nèi)容步驟和注意事項(xiàng),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
教你C#將CSV轉(zhuǎn)為Excel的實(shí)現(xiàn)方法
這篇文章主要介紹了C#?將CSV轉(zhuǎn)為Excel,轉(zhuǎn)換之后可執(zhí)行更多關(guān)于數(shù)據(jù)編輯、格式設(shè)置等操作,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-03-03
C#連接到sql server2008數(shù)據(jù)庫(kù)的實(shí)例代碼
這篇文章主要介紹了C#連接到sql server2008數(shù)據(jù)庫(kù)的實(shí)例代碼,需要的朋友可以參考下2017-09-09
C#實(shí)現(xiàn)廣度優(yōu)先搜索的實(shí)例代碼
廣度優(yōu)先搜索算法(BFS)是圖或樹搜索的重要算法,學(xué)習(xí)BFS能提高理解圖結(jié)構(gòu)的能力,對(duì)解決復(fù)雜圖問題有幫助,實(shí)際應(yīng)用包括網(wǎng)絡(luò)爬蟲、社交網(wǎng)絡(luò)分析、迷宮求解等,感興趣的可以了解一下2024-10-10
WPF運(yùn)行時(shí)替換方法實(shí)現(xiàn)mvvm自動(dòng)觸發(fā)刷新
這篇文章主要為大家詳細(xì)介紹了WPF運(yùn)行時(shí)如何實(shí)現(xiàn)setter不需要調(diào)方法就可以自動(dòng)觸發(fā)界面刷新,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
C#使用DataSet Datatable更新數(shù)據(jù)庫(kù)的三種實(shí)現(xiàn)方法
這篇文章主要介紹了C#使用DataSet Datatable更新數(shù)據(jù)庫(kù)的三種實(shí)現(xiàn)方法,需要的朋友可以參考下2014-08-08

