Unity中,基本的音乐音效控制系统
2022-04-02 本文已影响0人
全新的饭
说明
image.png
需在游戏一开始调用Init
GameObject.FindObjectOfType<Audio.AudioSys>().Init();
在游戏结束时调用Destroy
Audio.AudioSys.Instance?.Destroy();
外部可以修改音乐和音效的音量。
可传入声音资源(AudioClip)播放,也可传入资源路径(需在Resources目录下)。
如
Audio.AudioSys.Instance.PlaySound("声音资源路径");
播放音乐时,会有淡入淡出效果。
具体实现
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Audio
{
public class AudioSys : MonoBehaviour
{
[SerializeField]
private AudioSource _asMusic;
[SerializeField]
private AudioSource _asSound;
public static AudioSys Instance { get; private set; }
public float MusicVolume
{
get
{
return PlayerPrefs.GetFloat(MusicVolumeStorageKey, 0.5f);
}
set
{
value = Mathf.Clamp01(value);
_asMusic.volume = value;
PlayerPrefs.SetFloat(MusicVolumeStorageKey, value);
}
}
private const string MusicVolumeStorageKey = "AudioSysMusicVolume";
public float SoundVolume
{
get
{
return PlayerPrefs.GetFloat(SoundVolumeStorageKey, 0.5f);
}
set
{
value = Mathf.Clamp01(value);
_asSound.volume = value;
PlayerPrefs.SetFloat(SoundVolumeStorageKey, value);
}
}
private const string SoundVolumeStorageKey = "AudioSysSoundVolume";
private Dictionary<string, AudioClip> _soundClipDict;
private Dictionary<string, AudioClip> _musicClipDict;
public void Init()
{
if (Instance != null)
{
return;
}
Instance = this;
_asMusic.volume = MusicVolume;
_asSound.volume = SoundVolume;
#if UNITY_EDITOR
Debug.Log(string.Format("当前音乐和音效的音量分别是:{0},{1}", _asMusic.volume, _asSound.volume));
#endif
_soundClipDict = new Dictionary<string, AudioClip>();
_musicClipDict = new Dictionary<string, AudioClip>();
}
public void Destroy()
{
_soundClipDict.Clear();
_soundClipDict = null;
_musicClipDict.Clear();
_musicClipDict = null;
Instance = null;
}
public void PlaySound(AudioClip clip)
{
PlaySound(clip, _asSound);
}
public void PlaySound(AudioClip clip, AudioSource audioSource)
{
audioSource.volume = SoundVolume;
audioSource.PlayOneShot(clip);
}
public void PlaySound(string clipPath)
{
PlaySound(clipPath, _asSound);
}
public void PlaySound(string clipPath, AudioSource audioSource)
{
audioSource.volume = SoundVolume;
Play(clipPath, _soundClipDict, audioSource, PlaySound);
}
public void PlayMusic(string clipPath)
{
Play(clipPath, _musicClipDict, _asMusic, PlayMusic);
}
private void PlayMusic(AudioClip clip, AudioSource audioSource)
{
PlayMusic(clip);
}
public void PlayMusic(AudioClip clip)
{
StopPlayMusicCoroutine();
if (_asMusic.clip == null)
{
_asMusic.clip = clip;
_asMusic.loop = true;
_asMusic.Play();
}
else
{
StartPlayMusicCoroutine(clip);
}
}
private IEnumerator _playMusicCoroutine;
private IEnumerator PlayMusicCoroutine(AudioClip newClip)
{
float maxVolume = _asMusic.volume;
float minVolume = 0f;
float duration = 1f;
float timer = 0f;
while (timer < duration)
{
_asMusic.volume = Mathf.Lerp(maxVolume, minVolume, timer / duration);
timer += Time.deltaTime;
yield return null;
}
_asMusic.volume = minVolume;
_asMusic.clip = newClip;
_asMusic.Play();
maxVolume = MusicVolume;
timer = 0f;
while (timer < duration)
{
_asMusic.volume = Mathf.Lerp(minVolume, maxVolume, timer / duration);
timer += Time.deltaTime;
yield return null;
}
}
private void StartPlayMusicCoroutine(AudioClip newClip)
{
_playMusicCoroutine = PlayMusicCoroutine(newClip);
StartCoroutine(_playMusicCoroutine);
}
private void StopPlayMusicCoroutine()
{
if (_playMusicCoroutine != null)
{
StopCoroutine(_playMusicCoroutine);
_playMusicCoroutine = null;
}
}
private void Play(string clipPath, Dictionary<string, AudioClip> dict, AudioSource audioSource, Action<AudioClip, AudioSource> action)
{
if (!dict.ContainsKey(clipPath))
{
var clip = Resources.Load<AudioClip>(clipPath);
if (clip != null)
{
dict.Add(clipPath, clip);
#if UNITY_EDITOR
Debug.Log("添加声音资源到音频管理系统:" + clipPath);
#endif
}
}
if (dict.ContainsKey(clipPath))
{
action?.Invoke(dict[clipPath], audioSource);
}
}
}
}