Unity中,基本的音乐音效控制系统(改良)
相关文档原音效控制系统:Unity中,基本的音乐音效控制系统
按钮的点击效果(缩放、声音):Unity中,按钮按下抬起的缩放效果
改良内容
不再需要自行创建相关GO。当调用Instance时,若不存在,会自动创建相关的GO。
public AudioClip _clip;public AudioClip _music;Audio.AudioSys.Instance.PlaySound(_clip);Audio.AudioSys.Instance.PlayMusic(_music);using System;using System.Collections;using System.Collections.Generic;using UnityEngine;namespace Audio{ public class AudioSys : MonoBehaviour { private AudioSource _asMusic; private AudioSource _asSound; public const float SoundDefaultVolume = 1f; public const float MusicDefaultVolume = 0.5f; private static AudioSys _instance; public static AudioSys Instance { get { if (_instance == null) { GameObject go = new GameObject(nameof(AudioSys)); _instance = go.AddComponent<AudioSys>(); var parentGo = GameObject.Find("Singleton"); if (parentGo == null) { parentGo = new GameObject("Singleton"); UnityEngine.Object.DontDestroyOnLoad(parentGo); } go.transform.SetParent(parentGo.transform); _instance.Init(); } return _instance; } } #region 音量存储 public float MusicVolume { get { return PlayerPrefs.GetFloat(MusicVolumeStorageKey, MusicDefaultVolume); } 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, SoundDefaultVolume); } set { value = Mathf.Clamp01(value); _asSound.volume = value; PlayerPrefs.SetFloat(SoundVolumeStorageKey, value); } } private const string SoundVolumeStorageKey = "AudioSysSoundVolume"; #endregion private Dictionary<string, AudioClip> _soundClipDict; private Dictionary<string, AudioClip> _musicClipDict; private void Init() { // 创建 _asMusic 和 _asSound _asMusic = CreateAudioSourceGo("Music"); _asSound = CreateAudioSourceGo("Sound"); _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>(); } private AudioSource CreateAudioSourceGo(string goName) { GameObject go = new GameObject(goName); var audioSource = go.AddComponent<AudioSource>(); audioSource.playOnAwake = false; go.transform.SetParent(transform); return audioSource; } public void Destroy() { _soundClipDict.Clear(); _soundClipDict = null; _musicClipDict.Clear(); _musicClipDict = null; Destroy(Instance.gameObject); _instance = null; } #region 播放音效:可以使用外部AudioSource,也可直接传入音效。可直接传音效资源,也可直接传路径(必须在Resources目录下) 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); } #endregion public void PlayMusic(string clipPath) { Play(clipPath, _musicClipDict, _asMusic, PlayMusic); } public void PlayMusic(AudioClip clip) { StopPlayMusicCoroutine(); if (_asMusic.clip == null) { _asMusic.clip = clip; _asMusic.loop = true; _asMusic.Play(); } else { StartPlayMusicCoroutine(clip); } } private void PlayMusic(AudioClip clip, AudioSource audioSource) { PlayMusic(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.unscaledDeltaTime; 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.unscaledDeltaTime; yield return null; } _asMusic.volume = maxVolume; } 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, audioSource); } } }}
音效控制界面:AudioWnd
2个按钮,分别拥有2个状态:静音、非静音。通过点击在2个状态间切换。
image.png
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;// 2个开关,分别控制音乐、音效的音量。public class AudioWnd : MonoBehaviour{ private GameSys _gameSys; private GameObject _wndGo; private AudioWndBtn _musicBtn; private AudioWndBtn _soundBtn; private void OnEnable() { Open(); } private void Start() { Init(); } private void OnDisable() { Close(); } private void OnDestroy() { Destroy(); } public void Init() { _musicBtn.Button.onClick.AddListener(OnClickMusicBtn); _soundBtn.Button.onClick.AddListener(OnClickSoundBtn); Open(); } public void Destroy() { _musicBtn.Button.onClick.RemoveListener(OnClickMusicBtn); _soundBtn.Button.onClick.RemoveListener(OnClickSoundBtn); } private void Open() { RefreshBtnState(); _wndGo.SetActive(true); void RefreshBtnState() { _musicBtn.RefreshState(IsMute(Audio.AudioSys.Instance.MusicVolume)); _soundBtn.RefreshState(IsMute(Audio.AudioSys.Instance.SoundVolume)); } } private void Close() { _wndGo.SetActive(false); } private void OnClickMusicBtn() { bool isMute = IsMute(Audio.AudioSys.Instance.MusicVolume); Audio.AudioSys.Instance.MusicVolume = isMute ? Audio.AudioSys.MusicDefaultVolume : 0; _musicBtn.RefreshState(IsMute(Audio.AudioSys.Instance.MusicVolume)); } private void OnClickSoundBtn() { bool isMute = IsMute(Audio.AudioSys.Instance.SoundVolume); Audio.AudioSys.Instance.SoundVolume = isMute ? Audio.AudioSys.SoundDefaultVolume : 0; _soundBtn.RefreshState(IsMute(Audio.AudioSys.Instance.SoundVolume)); } private bool IsMute(float volume) { return volume == 0; } private class AudioWndBtn { public Button Button; public GameObject NonMuteGo; public GameObject MuteGo; public void RefreshState(bool isMute) { NonMuteGo.SetActive(!isMute); MuteGo.SetActive(isMute); } }}
页:
[1]