XGundam05 发表于 2022-6-29 10:10

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]
查看完整版本: Unity中,基本的音乐音效控制系统(改良)