Unity實現(xiàn)音頻播放管理器
更新時間:2020年09月17日 08:43:38 作者:SandmanRUN
這篇文章主要為大家詳細介紹了Unity實現(xiàn)音頻播放管理器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了Unity實現(xiàn)音頻播放管理器的具體代碼,供大家參考,具體內(nèi)容如下
1、模塊化,直接用。創(chuàng)建一個空物體,把此腳本拖上去,然后把需要播放的所有音頻拖到面板上的”AudioList“中;
2、通過AudioManagerP._instance直接調(diào)用方法,包含:
- 暫停;
- 繼續(xù)播放;
- 停止播放;
- 播放背景音樂(0號播放器專用于播放背景音);
- 直接播放聲音(帶參數(shù)1、播放器序號 2、音頻的名字 3、聲音大小 4、 是否循環(huán));
- 直接播放呻吟(帶參數(shù)1、播放器序號 2、音頻的名字);
- 聲音淡入(帶參數(shù)1、播放器序號 2、音頻的名字 3、 是否循環(huán));
- 聲音淡出(帶參數(shù) 播放器序號 )。
優(yōu)點:同時可以播放很多個聲音源,可以精確控制每個播放源的狀態(tài)
缺點:不知道。
源碼
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;
//初始聲音預設數(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;
//聲音對象池
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">播放器序號(用第幾個AudioSource播放)</param>
public void PauseAudio(int index)
{
AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>();
audioSource.Pause();
}
/// <summary>
/// 繼續(xù)播放
/// </summary>
/// <param name="index">播放器序號</param>
public void ResumeAudio(int index)
{
AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>();
audioSource.UnPause();
}
/// <summary>
/// 停止播放聲音
/// </summary>
/// <param name="index">播放器序號</param>
public void StopAudio(int index)
{
AudioSource audioSource = this.transform.GetChild(index).GetComponent<AudioSource>();
audioSource.Stop();
}
/// <summary>
/// 播放背景音樂,這里直接固定0號播放器用來播放北京音樂
/// </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">播放器序號</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("按鈕點擊的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">播放器序號</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("按鈕點擊的clip名字是:"+audioClip.name);
audioSource.gameObject.SetActive(true);
audioSource.clip = audioClip;
if (audioSource.isPlaying)
{
audioSource.Stop();
}
audioSource.Play();
}
}
/// <summary>
/// 聲音淡入
/// </summary>
/// <param name="index">播放器序號</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); //聲音播放對象默認為false,播放時把對應的對象設為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">淡出的播放器序號</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 聲音對象池
/*聲音對象池,待完善,可能存在同一時間多種聲音源在播放,硬切或者播放完畢再切,無法判定是那種,無法準確釋放AudioObjectPool
這里只是在開局使用對象池生成了指定個數(shù)的播放器,沒有用到獲取和釋放播放器對象*/
public class AudioObjectPool
{
//要生成的對象池預設
private GameObject prefab;
//對象池列表
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++)
{
//進行初始化
AllLocateInstance();
}
}
//獲取實例
public GameObject GetInstance()
{
if (pool.Count == 0)
{
//創(chuàng)建實例
}
GameObject instance = pool[0];
pool.RemoveAt(0);
instance.SetActive(true);
return instance;
}
//釋放實力
public void ReleaseInstance(GameObject instance)
{
instance.SetActive(false);
pool.Add(instance);
}
//生成本地實力
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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
相關文章
C# 調(diào)用API函數(shù)彈出映射網(wǎng)絡驅(qū)動器對話框問題
C#中的.net的常用對話框中沒有映射網(wǎng)絡驅(qū)動映射對話框,所以需要用windows的API函數(shù)去實現(xiàn)彈出映射網(wǎng)絡驅(qū)動器對話框2014-01-01
C#實現(xiàn)帶行數(shù)和標尺的RichTextBox
這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)帶行數(shù)和標尺的RichTextBox,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12
linux操作系統(tǒng)安裝MONO執(zhí)行C#程序的詳解步驟
這篇文章主要介紹了linux操作系統(tǒng)安裝MONO執(zhí)行C#程序詳解步驟,有需要的可以參考一下2013-12-12

