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

【Unity】音频管理器

[复制链接]
发表于 2022-6-9 20:59 | 显示全部楼层 |阅读模式
一个简单的音频管理器,可以播放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[clipName];                //未在缓存池里                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;        }    }}
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-9-22 07:21 , Processed in 0.096981 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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