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()
{
//測試代碼
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
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# 調(diào)用API函數(shù)彈出映射網(wǎng)絡(luò)驅(qū)動(dòng)器對(duì)話框問題
C#中的.net的常用對(duì)話框中沒有映射網(wǎng)絡(luò)驅(qū)動(dòng)映射對(duì)話框,所以需要用windows的API函數(shù)去實(shí)現(xiàn)彈出映射網(wǎng)絡(luò)驅(qū)動(dòng)器對(duì)話框2014-01-01
C#實(shí)現(xiàn)托盤程序并禁止多個(gè)應(yīng)用實(shí)例運(yùn)行的方法
這篇文章主要介紹了C#實(shí)現(xiàn)托盤程序并禁止多個(gè)應(yīng)用實(shí)例運(yùn)行的方法,涉及C#中NotifyIcon控件的使用及設(shè)置標(biāo)志位控制程序只運(yùn)行一個(gè)的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
C#實(shí)現(xiàn)帶行數(shù)和標(biāo)尺的RichTextBox
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)帶行數(shù)和標(biāo)尺的RichTextBox,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12
linux操作系統(tǒng)安裝MONO執(zhí)行C#程序的詳解步驟
這篇文章主要介紹了linux操作系統(tǒng)安裝MONO執(zhí)行C#程序詳解步驟,有需要的可以參考一下2013-12-12
C#傳值方式實(shí)現(xiàn)不同程序窗體間通信實(shí)例
Form2構(gòu)造函數(shù)中接收一個(gè)string類型參數(shù),即Form1中選中行的文本,將Form2的TextBox控件的Text設(shè)置為該string,即完成了Form1向Form2的傳值2013-12-12

