七彩极 发表于 2022-6-9 20:59

【Unity】音频管理器

一个简单的音频管理器,可以播放bgm和音效,声音音量控制
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;using XFramework.CoroutineTool;using XFramework.Singleton;namespace XFramework.Audio{    public class AudioManager : SingletonTemplate<AudioManager>    {      public Func<string, AudioClip> LoadFunc;      private GameObject audioRootGo;      /// <summary>      /// AudioSource缓存池      /// </summary>      private Queue<AudioSource> cacheAudioSource;      /// <summary>      /// 正在播放的所有音频对象      /// </summary>      private Dictionary<string, AudioSource> dicAudioSource;      /// <summary>      /// 当前的BGM      /// </summary>      private string curPlayBgmName;      #region 音量      private int volumeAudio;      private int volumeBGM;      public int VolumeAudio      {            get => volumeAudio;            set => volumeAudio = value;      }      public int VolumeBGM      {            get => volumeBGM;            set            {                volumeBGM = value;                var curBgm = GetCurPlayBgmAudioSource();                if (curBgm != null)                {                  curBgm.volume = volumeBGM;                }            }      }      #endregion      public void OnInit(Func<string, AudioClip> loadFunc)      {            cacheAudioSource = new Queue<AudioSource>(5);            dicAudioSource = new Dictionary<string, AudioSource>();            volumeAudio = 1;            volumeBGM = 1;            audioRootGo = new GameObject("AudioRoot");            GameObject.DontDestroyOnLoad(audioRootGo);            this.LoadFunc = loadFunc;      }      public void OnDisposs()      {            cacheAudioSource = null;            dicAudioSource = null;            curPlayBgmName = null;            GameObject.Destroy(audioRootGo);            audioRootGo = null;      }      public AudioSource GetCurPlayBgmAudioSource()      {            if (curPlayBgmName == null) return null;            AudioSource audioSource;            if (dicAudioSource.TryGetValue(curPlayBgmName, out audioSource))            {                return audioSource;            }            return null;      }      /// <summary>      /// 背景音乐      /// </summary>      /// <param name="clipName"></param>      /// <param name="volume"></param>      public void PlayBGM(string clipName, bool loop = false)      {            //停止之前的bgm            StopBgm();            curPlayBgmName = clipName;            Play(clipName, loop, (source) =>               {                     source.volume = VolumeBGM;                     source.spatialBlend = 0;               });      }      /// <summary>      /// 普通音效      /// </summary>      /// <param name="clip"></param>      /// <param name="volume"></param>      public void PlayAudio(string clipName, bool loop = false, float pitch = 1)      {            Play(clipName, loop, (source) =>                {                  source.volume = VolumeAudio;                  source.pitch = pitch;                  source.spatialBlend = 0;                });      }      /// <summary>      /// 3D音效      /// </summary>      /// <param name="clip"></param>      /// <param name="volume"></param>      /// <param name="position"></param>      public void Play3DAudio(string clipName, Vector3 position)      {            Play(clipName, false, (source) =>               {                     source.volume = VolumeAudio;                     source.spatialBlend = 1;                     source.transform.position = position;               });      }      /// <summary>      /// 停止所有音效,包括BGM      /// </summary>      public void StopAllAudio()      {            foreach (var audio in dicAudioSource)            {                StopPlayAudio(audio.Key);            }      }      private void Play(string clipName, bool isLoop, Action<AudioSource> onSetting = null)      {            //正在播放,就停掉之前的            if (dicAudioSource.ContainsKey(clipName))            {                StopPlayAudio(clipName);            }            AudioSource source = GetAudioSource();            onSetting?.Invoke(source);            var clip = LoadFunc(clipName);            if (clip == null)            {                LogTool.LogError("can not find the clip: " + clipName);                return;            }            source.clip = clip;            source.loop = isLoop;            source.Play();            dicAudioSource.Add(clipName, source);            //非循环播放的主动停止            if (isLoop)            {            }            else            {                LogTool.Log($"play audio, audio name:{clipName}, loop:{source.loop}", Log.LogColor.Green);                DelayTool.DelayDo(source.clip.length,                  (obj) =>                  {                        var clipName = obj as string;                        StopPlayAudio(clipName);                        //LogTool.Log($"stop audio, audio name:{clipName}, loop:{source.loop}", Log.LogColor.Green);                  }, clipName);            }      }      public void StopPlayAudio(string clipName)      {            //正在播放            if (dicAudioSource.ContainsKey(clipName))            {                var audioSource = dicAudioSource;                //未在缓存池里                if (!cacheAudioSource.Contains(audioSource))                {                  audioSource.Stop();                  audioSource.gameObject.SetActive(false);                  cacheAudioSource.Enqueue(audioSource);                }                dicAudioSource.Remove(clipName);            }      }      private void StopBgm()      {            if (!string.IsNullOrEmpty(curPlayBgmName))            {                StopPlayAudio(curPlayBgmName);                curPlayBgmName = null;            }      }      private AudioSource GetAudioSource()      {            AudioSource source;            //优先从缓存池里取            if (cacheAudioSource.Count > 0)            {                source = cacheAudioSource.Dequeue();                source.gameObject.SetActive(true);            }            else            {                GameObject gameObject = new GameObject("audio");                gameObject.transform.parent = audioRootGo.transform;                source = gameObject.AddComponent<AudioSource>();                source.spatialBlend = 1f;                source.loop = false;            }            return source;      }    }}
页: [1]
查看完整版本: 【Unity】音频管理器