找回密码
 立即注册
查看: 290|回复: 0

Unity中,基本的音乐音效控制系统(改良)

[复制链接]
发表于 2022-6-29 10:10 | 显示全部楼层 |阅读模式
相关文档

原音效控制系统: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[clipPath], 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;    [SerializeField]    private GameObject _wndGo;    [SerializeField, Header("按钮:音乐")]    private AudioWndBtn _musicBtn;    [SerializeField, Header("按钮:音效")]    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;    }    [System.Serializable]    private class AudioWndBtn    {        public Button Button;        [Header("外观:非静音")]        public GameObject NonMuteGo;        [Header("外观:静音")]        public GameObject MuteGo;        public void RefreshState(bool isMute)        {            NonMuteGo.SetActive(!isMute);            MuteGo.SetActive(isMute);        }    }}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-15 20:44 , Processed in 0.092000 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表