Unity游戏框架设计之音频管理器
简单介绍
在游戏中,主要的音频分为两种类型。第一种类型是 BGM(背景音乐),第二种类型是音效。BGM 的特点是音频持续时间长,一般在游戏中的同一时间内只能播放一个 BGM。音效的特点是音频持续时间短,一般在游戏中的同一时间内允许同时播放多个音效。
在下述代码中,实现了对 BGM 音量和音效音量的全局配置。玩家可以在游戏的设置 UI 中配置 BGM 音量和音效音量。同时实现了播放 BGM 和播放音效的功能,以及音频的生命周期方法。
代码设计
public class AudioManager : SingletonMono<AudioManager>
{
private static AudioMixer _audioMixer;
private static string _audioMixerGroupBGMPath;
private static string _audioMixerGroupSoundsPath;
private static string _bgmVolumeParameter;
private static string _soundVolumeParameter;
private readonly Dictionary<string, AudioClip> _audioClipSet = new();
public static void Initialize(string audioMixerAssetPath, string audioMixerGroupBGMPath, string audioMixerGroupSoundsPath,
string audioMixerBGMVolumeParameter, string audioMixerSoundsVolumeParameter)
{
_audioMixer = ResourceManager.Instance.LoadAsset<AudioMixer>(audioMixerAssetPath);
_audioMixerGroupBGMPath = audioMixerGroupBGMPath;
_audioMixerGroupSoundsPath = audioMixerGroupSoundsPath;
_bgmVolumeParameter = audioMixerBGMVolumeParameter;
_soundVolumeParameter = audioMixerSoundsVolumeParameter;
}
public void ConfigBGMVolume(float bgmVolume)
{
if (FloatUtils.IsEqualsTo(bgmVolume, 0f))
{
_audioMixer.SetFloat(_bgmVolumeParameter, -80);
return;
}
_audioMixer.SetFloat(_bgmVolumeParameter, 5f / Mathf.Log10(2) * Mathf.Log10(bgmVolume));
}
public void ConfigSoundsVolume(float soundsVolume)
{
if (FloatUtils.IsEqualsTo(soundsVolume, 0f))
{
_audioMixer.SetFloat(_soundVolumeParameter, -80);
return;
}
_audioMixer.SetFloat(_soundVolumeParameter, 5f / Mathf.Log10(2) * Mathf.Log10(soundsVolume));
}
public void PlayBGM(GameObject target, string audioAssetPath)
{
if (!_audioClipSet.ContainsKey(audioAssetPath))
{
LoadAsset(audioAssetPath);
}
SetBGM(target, audioAssetPath);
PlayBGM(target);
}
public void PlaySound(GameObject target, string audioAssetPath)
{
if (!_audioClipSet.ContainsKey(audioAssetPath))
{
LoadAsset(audioAssetPath);
}
SetSounds(target, audioAssetPath);
PlaySound(target);
}
public void PlaySound(GameObject target, List<string> audioAssetPathSet)
{
if (audioAssetPathSet.Count == 1)
{
PlaySound(target, audioAssetPathSet[0]);
return;
}
foreach (string audioAssetPath in audioAssetPathSet)
{
if (!_audioClipSet.ContainsKey(audioAssetPath))
{
LoadAsset(audioAssetPath);
}
}
foreach (string audioAssetPath in audioAssetPathSet)
{
SetSounds(target, audioAssetPath);
PlaySound(target);
}
}
public void Stop(GameObject target)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
return;
}
if (audioSource.clip == null)
{
return;
}
if (!audioSource.isPlaying)
{
return;
}
audioSource.Stop();
}
public void Pause(GameObject target)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
return;
}
if (audioSource.clip == null)
{
return;
}
if (!audioSource.isPlaying)
{
return;
}
audioSource.Pause();
}
public void UnPause(GameObject target)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
return;
}
if (audioSource.clip == null)
{
return;
}
if (audioSource.isPlaying)
{
return;
}
audioSource.UnPause();
}
private void LoadAsset(string audioAssetPath)
{
_audioClipSet[audioAssetPath] = ResourceManager.Instance.LoadAsset<AudioClip>(audioAssetPath);
}
private void UnloadAsset(string audioAssetPath)
{
if (!_audioClipSet.ContainsKey(audioAssetPath))
{
return;
}
AudioClip audioClip = _audioClipSet[audioAssetPath];
if (audioClip == null)
{
return;
}
Destroy(audioClip);
_audioClipSet.Remove(audioAssetPath);
}
private void SetBGM(GameObject target, string bgmAssetPath)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = target.AddComponent<AudioSource>();
}
if (!_audioClipSet.ContainsKey(bgmAssetPath))
{
return;
}
AudioClip audioClip = _audioClipSet[bgmAssetPath];
if (audioClip == null)
{
return;
}
audioSource.outputAudioMixerGroup = _audioMixer.FindMatchingGroups(_audioMixerGroupBGMPath)[0];
audioSource.clip = audioClip;
}
private void SetSounds(GameObject target, string soundAssetPath)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = target.AddComponent<AudioSource>();
}
if (!_audioClipSet.ContainsKey(soundAssetPath))
{
return;
}
AudioClip audioClip = _audioClipSet[soundAssetPath];
if (audioClip == null)
{
return;
}
audioSource.outputAudioMixerGroup = _audioMixer.FindMatchingGroups(_audioMixerGroupSoundsPath)[0];
audioSource.clip = audioClip;
}
private void PlayBGM(GameObject target)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
return;
}
if (audioSource.clip == null)
{
return;
}
if (audioSource.isPlaying)
{
return;
}
audioSource.playOnAwake = false;
audioSource.loop = true;
audioSource.Play();
}
private void PlaySound(GameObject target)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
return;
}
if (audioSource.clip == null)
{
return;
}
audioSource.playOnAwake = false;
audioSource.loop = false;
audioSource.PlayOneShot(audioSource.clip);
}
private void UnsetAudio(GameObject target)
{
AudioSource audioSource = target.GetComponent<AudioSource>();
if (audioSource == null)
{
return;
}
audioSource.Stop();
audioSource.clip = null;
}
}
代码说明
(一)实现 BGM 和音效的音量大小的全局控制。
(二)实现播放 BGM 和播放音效的功能。
(三)实现对音频生命周期的控制,包括播放、暂停、恢复和停止操作。
后记
由于个人能力有限,文中不免存在疏漏之处,恳求大家斧正,一起交流,共同进步。
标签:return,target,audioSource,audioAssetPath,音频,Unity,管理器,null,string From: https://www.cnblogs.com/kkelin/p/18168086