音频管理器
下面展示一些 内联代码片
。
// An highlighted block
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class AudioManager : MonoBehaviour
{
private List<AudioSource> m_SfxList = new List<AudioSource>();
private Dictionary<string, GameObject> m_SfxSingleDict = new Dictionary<string, GameObject>();
private Dictionary<string, GameObject> m_BgmDict = new Dictionary<string, GameObject>();
public void Init()
{
SceneManager.sceneUnloaded += CleanUnused;
}
private void OnDestroy()
{
SceneManager.sceneUnloaded -= CleanUnused;
}
/// <summary>
/// 播放音效,重复调用时会播放多次
/// </summary>
/// <param name="audioName">音频名称</param>
/// <param name="volume">音量大小</param>
/// <param name="crossScene">是否可以跨场景播放</param>
/// <param name="duration">延迟销毁,0表示音频播放完就会自动销毁</param>
public void PlaySFX(string audioName, float volume = 1f, bool crossScene = false, float duration = 0f)
{
AudioClip audioClip = GameRoot.Instance.ResourceManager.LoadAudioClip(audioName);
GameObject sfxGo = new GameObject("SFX");
sfxGo.transform.parent = transform;
sfxGo.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
AudioSource source = sfxGo.AddComponent<AudioSource>();
source.playOnAwake = false;
source.clip = audioClip;
source.volume = volume;
source.loop = false;
source.spatialBlend = 0f;
source.Play();
if (crossScene == false)
{
m_SfxList.Add(source);
}
// 销毁自身
if (duration == 0f)
{
duration = audioClip.length;
}
GameRoot.Instance.TimerManager.AddTimeTask((id) =>
{
if (m_SfxList.Contains(source))
{
m_SfxList.Remove(source);
}
Destroy(sfxGo);
}, duration);
}
/// <summary>
/// 播放音效,重复调用时不会再次播放,不能跨场景播放
/// </summary>
/// <param name="audioName">音频名称</param>
/// <param name="volume">音量大小</param>
/// <param name="duration">延迟销毁,0表示音频播放完就会自动销毁</param>
public void PlaySFXSingle(string audioName, float volume = 1f, float duration = 0f)
{
if (m_SfxSingleDict.ContainsKey(audioName))
{
return;
}
AudioClip audioClip = GameRoot.Instance.ResourceManager.LoadAudioClip(audioName);
GameObject sfxGo = new GameObject("SFXSingle");
sfxGo.transform.parent = transform;
sfxGo.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
m_SfxSingleDict.Add(audioName, sfxGo);
AudioSource source = sfxGo.AddComponent<AudioSource>();
source.playOnAwake = false;
source.clip = audioClip;
source.volume = volume;
source.loop = false;
source.spatialBlend = 0f;
source.Play();
// 销毁自身
if (duration == 0f)
{
duration = audioClip.length;
}
GameRoot.Instance.TimerManager.AddTimeTask((id) =>
{
if (m_SfxSingleDict.ContainsKey(audioName))
{
m_SfxSingleDict.Remove(audioName);
Destroy(sfxGo);
}
}, duration);
}
/// <summary>
/// 播放背景音,重复调用不会多次播放
/// </summary>
/// <param name="audioName">音频名称</param>
/// <param name="volume">音量大小</param>
public void PlayBgm(string audioName, float volume = 1f)
{
if (m_BgmDict.ContainsKey(audioName))
{
//Debug.LogErrorFormat("此BGM:{0} 已在播放中,请检查!", audioName);
return;
}
AudioClip audioClip = GameRoot.Instance.ResourceManager.LoadAudioClip(audioName);
GameObject bgmGo = new GameObject("BGM");
bgmGo.transform.parent = transform;
bgmGo.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
m_BgmDict.Add(audioName, bgmGo);
AudioSource source = bgmGo.AddComponent<AudioSource>();
source.playOnAwake = false;
source.clip = audioClip;
source.volume = volume;
source.loop = true;
source.spatialBlend = 0f;
source.Play();
}
/// <summary>
/// 停止指定BGM
/// </summary>
public void StopBgm(string audioName)
{
if (m_BgmDict.ContainsKey(audioName))
{
Destroy(m_BgmDict[audioName]);
m_BgmDict.Remove(audioName);
}
}
private void CleanUnused(Scene scene)
{
for (int i = 0; i < m_SfxList.Count; i++)
{
m_SfxList[i].Stop();
}
m_SfxList.Clear();
foreach (var sfxSingleKeyAndValue in m_SfxSingleDict)
{
Destroy(sfxSingleKeyAndValue.Value);
}
m_SfxSingleDict.Clear();
foreach (var bgmKeyAndValue in m_BgmDict)
{
Destroy(bgmKeyAndValue.Value);
}
m_BgmDict.Clear();
}
private Dictionary<string, AudioClip> m_AudioClipCacheDict = new Dictionary<string, AudioClip>();
/// <summary>
/// 加载音频
/// </summary>
/// <param name="audioName">音频名称</param>
/// <param name="cached">是否缓存</param>
public AudioClip LoadAudioClip(string audioName, bool cached = true)
{
string audioPath = string.Format("Audios/" + audioName);
m_AudioClipCacheDict.TryGetValue(audioPath, out AudioClip result);
if (result == null)
{
result = Resources.Load<AudioClip>(audioPath);
if (result == null)
{
Debug.LogError("请检查音频是否存在:" + audioPath);
return result;
}
if (cached == true)
{
m_AudioClipCacheDict.Add(audioPath, result);
}
}
return result;
}
}