class="markdown_views prism-tomorrow-night">
Unity的音频管理器
public class MusicManager : MonoBehaviour
{
#region 单例
private static MusicManager instance = null;
public static MusicManager Instance
{
get
{
GameObject musicMgr = GameObject.Find("MusicManager");
if (musicMgr == null)
{
musicMgr = new GameObject("MusicManager");
}
if (instance == null)
{
instance = musicMgr.GetComponent();
if (instance == null)
{
instance = musicMgr.AddComponent();
}
}
return instance;
}
}
#endregion
private AudioSource musicAudioSource;//背景音乐的AudioSource
private List unusedSoundAudioSourceList; // 存放可以使用的音频组件
private List usedSoundAudioSourceList; // 存放正在使用的音频组件
private Dictionary audioClipDict; // 缓存音频文件
private float musicVolume = 1; //背景音乐声音
private float soundVolume = 1; //音效声音
public string musicVolumePrefs = "MusicVolume";//本地缓存背景音乐的键
public string soundVolumePrefs = "SoundVolume";//本地缓存音效的键
private int poolCount = 5; // AudioSource对象池数量
void Awake()
{
//初始化
musicAudioSource = gameObject.AddComponent();
unusedSoundAudioSourceList = new List();
usedSoundAudioSourceList = new List();
audioClipDict = new Dictionary();
DontDestroyOnLoad(this.gameObject);
}
void Start() { }
public void Init()
{
// 从本地缓存读取声音音量
if (PlayerPrefs.HasKey(musicVolumePrefs))
{
musicVolume = PlayerPrefs.GetFloat(musicVolumePrefs,1);
}
if (PlayerPrefs.HasKey(soundVolumePrefs))
{
soundVolume = PlayerPrefs.GetFloat(soundVolumePrefs,1);
}
}
///
/// 播放背景音乐
///
/// 路径
/// 是否循环
public void PlayMusic(string path, bool isLoop = true)
{
//TODO背景音乐的淡入淡出用DOTWEEN
musicAudioSource.clip = GetAudioClip(path);
musicAudioSource.clip.LoadAudioData();
musicAudioSource.loop = isLoop;
musicAudioSource.volume = musicVolume;
musicAudioSource.Play();
}
///
/// 播放音效
///
/// 音效路径
/// 回调
public void PlaySound(string path, LuaFunction func)
{
AudioSource audioSource = null;
if (unusedSoundAudioSourceList.Count != 0)
{
audioSource = UnusedToUsed();
}
else
{
AddAudioSource();
audioSource = UnusedToUsed();
}
audioSource.clip = GetAudioClip(path);
audioSource.clip.LoadAudioData();
audioSource.volume = soundVolume;
audioSource.loop = false;
audioSource.Play();
StartCoroutine(WaitPlayEnd(audioSource, func));
}
///
/// 播放3d音效
///
///
///
public void Play3dSound(string path, Vector3 position)
{
AudioClip ac = GetAudioClip(path);
AudioSource.PlayClipAtPoint(ac, position);
}
///
/// 设置音量
///
/// 背景音乐的音量
/// 音效的音量
public void SetVolume(float music,float sound)
{
ChangeMusicVolume(music);
ChangeSoundVolume(sound);
}
///
/// 获取音频文件,获取后会缓存一份
///
///
///
private AudioClip GetAudioClip(string path)
{
if (audioClipDict.ContainsKey(path) == false)
{
AudioClip ac = Resources.Load(path) as AudioClip;
if (ac == null)
{
Debug.LogError("音频在Resource中不存在,请检查音频资源--path" + path);
return null;
}
audioClipDict.Add(path, ac);
}
return audioClipDict[path];
}
///
/// 添加音频组件
///
///
private AudioSource AddAudioSource()
{
if (unusedSoundAudioSourceList.Count != 0)
{
return UnusedToUsed();
}
else
{
AudioSource audioSource = gameObject.AddComponent();
unusedSoundAudioSourceList.Add(audioSource);
return audioSource;
}
}
///
/// 将未使用的音频组件移至已使用集合里
///
///
private AudioSource UnusedToUsed()
{
AudioSource audioSource = unusedSoundAudioSourceList[0];
unusedSoundAudioSourceList.RemoveAt(0);
usedSoundAudioSourceList.Add(audioSource);
return audioSource;
}
///
/// 当播放音效结束后,将其移至未使用集合
///
///
///
IEnumerator WaitPlayEnd(AudioSource audioSource, LuaFunction func)
{
yield return new WaitUntil(() => { return !audioSource.isPlaying; });
UsedToUnused(audioSource);
if (func != null)
{
func.Call();
func.Dispose();
func = null;
}
}
///
/// 将使用完的音频组件移至未使用集合里
///
///
private void UsedToUnused(AudioSource audioSource)
{
if (usedSoundAudioSourceList.Contains(audioSource))
{
usedSoundAudioSourceList.Remove(audioSource);
}
if (unusedSoundAudioSourceList.Count >= poolCount)
{
Destroy(audioSource);
}
else if (audioSource != null && !unusedSoundAudioSourceList.Contains(audioSource))
{
unusedSoundAudioSourceList.Add(audioSource);
}
}
///
/// 修改背景音乐音量
///
///
private void ChangeMusicVolume(float volume)
{
musicVolume = volume;
musicAudioSource.volume = volume;
PlayerPrefs.SetFloat(musicVolumePrefs, volume);
}
///
/// 修改音效音量
///
///
private void ChangeSoundVolume(float volume)
{
soundVolume = volume;
for (int i = 0; i < unusedSoundAudioSourceList.Count; i++)
{
unusedSoundAudioSourceList[i].volume = volume;
}
for (int i = 0; i < usedSoundAudioSourceList.Count; i++)
{
usedSoundAudioSourceList[i].volume = volume;
}
PlayerPrefs.SetFloat(soundVolumePrefs, volume);
}