框架搭建

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);
            }
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读