IndieGame/client/Assets/Ether/Scripts/Module/Audio/AudioManager.cs

294 lines
7.6 KiB
C#
Raw Permalink Normal View History

2024-10-11 10:12:15 +08:00
/********************************************************************
: AudioMgr.cs
:
: 1982614048@qq.com
: 2024/03/29 17:28:19
:
: 2024/04/03 17:09:26
:
*********************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Ether
{
public class AudioManager : SingletonAutoMono<AudioManager>
{
private AudioSource backGroundSource; //背景音乐Source
private List<AudioSource> allEffectSource = new List<AudioSource>(); //所有播放音效Source
private Dictionary<string, AudioClip> clipCache = new Dictionary<string, AudioClip>(); //clip缓存
private int releaseCount = 3; //空闲source大于这个数量时释放
/// <summary>
/// 全局音量
/// </summary>
[SerializeField, SetProperty("GlobalVolume"), Range(0f, 1f)]
private float globalVolume = 1f;
public float GlobalVolume
{
get => globalVolume;
set
{
globalVolume = value;
RefreshGlobalVolume();
}
}
/// <summary>
/// 背景音量
/// </summary>
[SerializeField, SetProperty("BackGroundVolume"), Range(0f, 1f)]
private float backGroundVolume = 1f;
public float BackGroundVolume
{
get => backGroundVolume;
set
{
backGroundVolume = value;
RefreshBackGroundVolume();
}
}
/// <summary>
/// 音效音量
/// </summary>
[SerializeField, SetProperty("EffectVolume"), Range(0f, 1f)]
private float effectVolume = 1f;
public float EffectVolume
{
get => effectVolume;
set
{
effectVolume = value;
RefreshEffectVolume();
}
}
/// <summary>
/// 是否静音
/// </summary>
[SerializeField, SetProperty("IsMute")]
private bool isMute = false;
public bool IsMute
{
get => isMute;
set
{
isMute = value;
RefreshGlobalVolume();
}
}
/// <summary>
/// 刷新全局音量
/// </summary>
private void RefreshGlobalVolume()
{
RefreshBackGroundVolume();
RefreshEffectVolume();
}
/// <summary>
/// 刷新背景音量
/// </summary>
private void RefreshBackGroundVolume()
{
backGroundSource.volume = globalVolume * backGroundVolume;
backGroundSource.mute = isMute;
}
/// <summary>
/// 刷新音效音量
/// </summary>
private void RefreshEffectVolume()
{
foreach (var source in allEffectSource)
{
source.volume = globalVolume * effectVolume;
source.mute = isMute;
}
}
/// <summary>
/// 播放背景音乐
/// </summary>
public void PlayBgAudio(string name)
{
AudioClip clip = GetAudioClip($"Audio/{name}");
RefreshBackGroundVolume();
Play(backGroundSource, clip, true);
}
public bool IsPlayingBgAudio()
{
return backGroundSource.isPlaying;
}
/// <summary>
/// 停止背景音乐
/// </summary>
public void StopBgAudio()
{
backGroundSource?.Stop();
}
/// <summary>
/// 播放
/// </summary>
private void Play(AudioSource source, AudioClip clip, bool isLoop = false)
{
source.clip = clip;
source.loop = isLoop;
source.mute = isMute;
source.Play();
}
/// <summary>
/// 播放音效
/// </summary>
public void PlayEffectAudio(string name, bool isLoop = false)
{
AudioClip clip = GetAudioClip($"Audio/{name}");
if (clip == null)
{
return;
}
AudioSource tmpSouce = GetFreeEffectSource();
RefreshEffectVolume();
Play(tmpSouce, clip, isLoop);
}
/// <summary>
/// 停止音效
/// </summary>
/// <param name="name"></param>
public void StopEffectAudio(string name)
{
foreach (var source in allEffectSource)
{
if (source.clip.name == name && source.isPlaying)
{
source.Stop();
}
}
}
/// <summary>
/// 停止所有音效
/// </summary>
public void StopAllEffectAudio()
{
foreach (var source in allEffectSource)
{
source.Stop();
}
}
/// <summary>
/// 是否正在播放某个音效
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public bool IsPlayingEffectAudio(string name)
{
foreach (var source in allEffectSource)
{
if (source.clip.name == name && source.isPlaying)
{
return true;
}
}
return false;
}
/// <summary>
/// 根据名字获取clip
/// </summary>
private AudioClip GetAudioClip(string name)
{
if (clipCache.ContainsKey(name))
{
return clipCache[name];
}
AudioClip clip = LoaderTools.LoadAsset<AudioClip>(name);
if (clip != null)
{
clipCache.Add(name, clip);
}
return clip;
}
/// <summary>
/// 获取一个空闲的AudioSource
/// </summary>
/// <returns></returns>
private AudioSource GetFreeEffectSource()
{
foreach (var souce in allEffectSource)
{
if (!souce.isPlaying)
{
ReleaseSurplus();
return souce;
}
}
AudioSource tmpSouce = gameObject.AddComponent<AudioSource>();
allEffectSource.Add(tmpSouce);
return tmpSouce;
}
/// <summary>
/// 释放空闲的AudioSource
/// </summary>
private void ReleaseSurplus()
{
int freeCount = 0;
List<AudioSource> remove = new List<AudioSource>();
foreach (var source in allEffectSource)
{
if (!source.isPlaying)
{
freeCount++;
if (freeCount > releaseCount)
{
remove.Add(source);
}
}
}
foreach (var source in remove)
{
allEffectSource.Remove(source);
Destroy(source);
}
remove.Clear();
}
public override void Init()
{
Clear();
if (backGroundSource == null)
{
backGroundSource = gameObject.AddComponent<AudioSource>();
}
RefreshGlobalVolume();
}
public override void Clear()
{
allEffectSource.Clear();
clipCache.Clear();
}
}
}