YanCheng_Metrology/Assets/Scripts/ProjectBase/MusicManager/MusicManager.cs

255 lines
6.9 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// 音效 音乐管理器
/// 2D声音全局
/// 管理音乐、音效播放 暂停、声音大小管理
/// </summary>
public class MusicManager : BaseManager<MusicManager>
{
private MusicManager()
{
musicObject = new GameObject("MusicObject");
GameObject.DontDestroyOnLoad(musicObject);
musicObject.transform.position = Vector3.zero;
MonoMgr.Instance.AddUpdateListener(Update);
}
/// <summary>
/// 音乐音效组件挂在的对象
/// </summary>
private readonly GameObject musicObject;
/// <summary>
/// 背景音乐播放组件
/// </summary>
private AudioSource backMusicSource;
/// <summary>
/// 播放音效组件
/// </summary>
private readonly List<AudioSource> audioSources = new List<AudioSource>();
/// <summary>
/// 缓存池中的音效组件
/// </summary>
private readonly List<AudioSource> audioSourcesCache =new List<AudioSource>();
/// <summary>
/// 标记音效暂停
/// </summary>
private bool isPauseSound = false;
/// <summary>
/// 播放背景音乐
/// </summary>
/// <param name="clipName">b背景音乐资源文件名 Resources下路径名+文件名,不需要文件格式</param>
/// <param name="volume">背景音乐声音大小</param>
public void PlayBackMusic(string clipName,float volume)
{
ResourcesManager.Instance.LoadAsync<AudioClip>(clipName, (clip) =>
{
if (!clip)
{
Debug.Log("资源加载失败!请检查文件名");
}
//背景音乐播放组件 唯一
if (backMusicSource == null)
backMusicSource = musicObject.AddComponent<AudioSource>();
backMusicSource.playOnAwake = false;
//背景音乐声音 这个音乐根据项目 会有独立的设置数据 从设置数据传过来
backMusicSource.volume = volume;
//背景音乐 文件
backMusicSource.clip = clip;
//循环播放
backMusicSource.loop = true;
//播放
backMusicSource.Play();
});
}
/// <summary>
/// 暂停背景音乐
/// </summary>
public void PauseBackMusic()
{
if (backMusicSource == null)
return;
backMusicSource.Pause();
}
/// <summary>
/// 恢复播放
/// </summary>
public void UnPauseBackMusic()
{
if (backMusicSource == null)
return;
backMusicSource.UnPause();
}
/// <summary>
/// 停止背景音乐
/// </summary>
public void StopBackMusic()
{
if (backMusicSource == null)
return;
backMusicSource.Stop();
}
/// <summary>
/// 改变背景音乐声音大小
/// </summary>
/// <param name="volume">声音值</param>
public void ChangeBackMusic(float volume)
{
if (backMusicSource == null)
return;
backMusicSource.volume = volume;
}
/// <summary>
/// 背景音乐 静音
/// </summary>
/// <param name="isMute"></param>
public void MuteMusic(bool isMute)
{
if (backMusicSource == null)
return;
backMusicSource.mute = isMute;
}
/// <summary>
/// 播放音效
/// </summary>
/// <param name="soundName">路径+音效文件名 不需要文件格式</param>
/// <param name="volume">音效声音</param>
/// <param name="isLoop">是否循环播放</param>
/// <param name="action">获取音效播放组件</param>
public void PlaySound(string soundName, float volume = 1, bool isLoop = false, UnityAction<AudioSource> action = null)
{
ResourcesManager.Instance.LoadAsync<AudioClip>(soundName, (clip) =>
{
AudioSource audioSource;
if (audioSourcesCache.Count==0)
{
audioSource = musicObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSourcesCache.Add(audioSource);
}
audioSource = audioSourcesCache[0];
audioSourcesCache.RemoveAt(0);
//设置声音大小
audioSource.volume = volume;
//设置音效资源
audioSource.clip = clip;
//循环
audioSource.loop = isLoop;
//激活
audioSource.enabled = true;
//播放
audioSource.Play();
//记录音效组件 这个有可能在多个地方同时调用 需要用锁
lock (this)
{
audioSources.Add(audioSource);
}
//播放音效后 获取音效组件
action?.Invoke(audioSource);
});
}
/// <summary>
/// 暂停所有音效
/// </summary>
public void PauseSound()
{
isPauseSound= true;
lock (this)
{
for (int i = 0; i < audioSources.Count; i++)
{
audioSources[i].Pause();
}
}
}
/// <summary>
/// 重新播放所有正在播放的音效
/// </summary>
public void UnPauseSounds()
{
isPauseSound = false;
lock (this)
{
for (int i = 0; i < audioSources.Count; i++)
{
audioSources[i].UnPause();
}
}
}
/// <summary>
/// 静音 音效
/// </summary>
/// <param name="isMute"></param>
public void MuteSound(bool isMute)
{
lock(this)
{
for (int i = 0; i < audioSources.Count; i++)
{
audioSources[i].mute = isMute;
}
}
}
/// <summary>
/// 改变音效声音
/// </summary>
/// <param name="volume"></param>
public void ChangeSoundVolume(float volume)
{
lock (this)
{
for (int i = 0; i < audioSources.Count; i++)
{
audioSources[i].volume = volume;
}
}
}
/// <summary>
/// 检测音效是否播放完 对播放完的音效进行删除 考虑性能 使用缓存池
/// </summary>
private void Update()
{
lock (this)
{
for (int i = audioSources.Count-1 ; i >= 0; i--)
{
if (!audioSources[i].isPlaying && !isPauseSound)
{
audioSources[i].clip = null;
audioSources[i].mute = false;
audioSources[i].loop = false;
audioSources[i].enabled = false;
audioSourcesCache.Add(audioSources[i]);
audioSources.RemoveAt(i);
}
}
}
}
~MusicManager()
{
MonoMgr.Instance.RemoveUpdateListener(Update);
}
}