界面音效以及3D音效通过参数控制声音加载声音资源包

补充博客把音效的课件加进来

 

namespace YouYou
{
    /// <summary>
    /// 音频组件
    /// </summary>
    public class AudioComponent : YouYouBaseComponent, IUpdateComponent
    {
        private AudioManager m_AudioManager;

        [Header("释放间隔")]
        [SerializeField]
        private int m_ReleaseInterval = 120;


        protected override void OnAwake()
        {
            base.OnAwake();
            m_AudioManager = new AudioManager(m_ReleaseInterval);
            GameEntry.RegisterUpdateComponent(this);
        }
        public void OnUpdate()
        {
            m_AudioManager.OnUpdate();
        }
        public override void Shutdown()
        {
            GameEntry.RemoveUpdateComponent(this);

            ShopAllAudio();
            StopBGM();
        }

        /// <summary>
        /// 加载音频文件
        /// </summary>
        /// <param name="onComplete"></param>
        public void LoadBanks(BaseAction onComplete)
        {
            m_AudioManager.LoadBanks(onComplete);
        }

        #region BGM
        /// <summary>
        /// 播放BGM
        /// </summary>
        public void PlayBGM(int audioId)
        {
            Sys_AudioEntity entity = GameEntry.DataTable.DataTableManager.Sys_AudioDBModel.GetDic(audioId);
            if (entity != null)
            {
                PlayBGM(entity.AssetPath, entity.Volume);
            }
            else
            {
                GameEntry.LogError("BGM不存在ID={0}", audioId);
            }
        }
        /// <summary>
        /// 播放BGM
        /// </summary>
        public void PlayBGM(string assetPath, float volume = 1)
        {
            m_AudioManager.PlayBGM(assetPath, volume);
        }
        /// <summary>
        /// 设置BGM音量
        /// </summary>
        /// <param name="value"></param>
        public void SetBGMVolume(float value)
        {
            m_AudioManager.SetBGMVolume(value);
        }
        /// <summary>
        /// 暂停BGM
        /// </summary>
        /// <param name="pause"></param>
        public void PauseBGM(bool pause)
        {
            m_AudioManager.PauseBGM(pause);
        }
        /// <summary>
        /// 停止播放BGM
        /// </summary>
        public void StopBGM()
        {
            m_AudioManager.StopBGM();
        }
        /// <summary>
        /// 开始播放BGM
        /// </summary>
        public void StartBGM()
        {
            m_AudioManager.StartBGM();
        }
        #endregion

        #region 音效
        /// <summary>
        /// 播放音效
        /// </summary>
        public int PlayAydio(int audioId, string parameterName = null, float value = 0, Vector3 pos3D = default)
        {
            Sys_AudioEntity entity = GameEntry.DataTable.DataTableManager.Sys_AudioDBModel.GetDic(audioId);
            if (entity != null)
            {
                return PlayAydio(entity.AssetPath, entity.Volume, parameterName, value, entity.Is3D == 1, pos3D);
            }
            else
            {
                GameEntry.LogError("Audio不存在Id = {0}", audioId);
                return -1;
            }
        }
        /// <summary>
        /// 播放音效
        /// </summary>
        public int PlayAydio(string assetPath, float volume, string parameterName, float value, bool is3D, Vector3 pos3D)
        {
            return m_AudioManager.PlayAudio(assetPath, volume, parameterName, value, is3D, pos3D);
        }

        /// <summary>
        /// 设置音效参数
        /// </summary>
        public void SetParameterForAudio(int serialId, string parameterName, float value)
        {
            m_AudioManager.SetParameterForAudio(serialId, parameterName, value);
        }

        /// <summary>
        /// 暂停某个音效
        /// </summary>
        /// <param name="serialId"></param>
        /// <param name="paused"></param>
        /// <returns></returns>
        public bool PausedAudio(int serialId, bool paused = true)
        {
            return m_AudioManager.PausedAudio(serialId, paused);
        }

        /// <summary>
        /// 停止某个音效
        /// </summary>
        /// <param name="serialId"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        internal bool StopAudio(int serialId, FMOD.Studio.STOP_MODE mode = FMOD.Studio.STOP_MODE.IMMEDIATE)
        {
            return m_AudioManager.StopAudio(serialId, mode);
        }
        /// <summary>
        /// 停止所有音效
        /// </summary>
        public void ShopAllAudio()
        {
            m_AudioManager.ShopAllAudio();
        }
        #endregion
    }
}

 

namespace YouYou
{
    /// <summary>
    /// 音频管理器
    /// </summary>
    public class AudioManager : ManagerBase
    {
        internal AudioManager(int releaseInterval)
        {
            m_ReleaseInterval = releaseInterval;
        }
        internal void OnUpdate()
        {
            //多长时间释放一次,是在Updata中
            if (Time.time > m_NextReleaseTime + m_ReleaseInterval)
            {
                m_NextReleaseTime = Time.time;
                Release();
            }
        }

        internal void LoadBanks(BaseAction onComplete)
        {
#if DISABLE_ASSETBUNDLE
            string[] arr = Directory.GetFiles(Application.dataPath + "/Download/Audio/", "*.bytes");
            for (int i = 0; i < arr.Length; i++)
            {
                FileInfo file = new FileInfo(arr[i]);
                TextAsset asset = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/Download/Audio/" + file.Name);
                RuntimeManager.LoadBank(asset);
            }
            if (onComplete != null) onComplete();
#elif ASSETBUNDLE
            GameEntry.Resource.ResourceLoaderManager.LoadAssetBundle(ConstDefine.AudioAssetBundlePath, onComplete: (AssetBundle bundle) =>
            {
                TextAsset[] arr = bundle.LoadAllAssets<TextAsset>();
                int len = arr.Length;
                for (int i = 0; i < len; i++)
                {
                    RuntimeManager.LoadBank(arr[i]);
                }
                if (onComplete != null) onComplete();
            });
#elif RESOURCES
            TextAsset[] assets = Resources.LoadAll<TextAsset>("Audio");
            for (int i = 0; i < assets.Length; i++)
            {
                RuntimeManager.LoadBank(assets[i]);
            }
            if (onComplete != null) onComplete();
#endif

        }

        #region BGM

        private string m_CurrBGMAudio;

        private float m_CurrBGMVolume;

        private float m_CurrBGMMaxVolume;

        private EventInstance BGMEvent;

        private TimeAction m_CurrBGMTimeAction;

        /// <summary>
        /// 播放BGM
        /// </summary>
        /// <param name="bgmPath"></param>
        internal void PlayBGM(string bgmPath, float volume = 1)
        {
            m_CurrBGMAudio = bgmPath;
            m_CurrBGMMaxVolume = volume;
            CheckBGMEventInstance();
        }
        /// <summary>
        /// BGM切换参数
        /// </summary>
        private void CheckBGMEventInstance(string switchName, float value)
        {
            BGMEvent.setParameterByName(switchName, value);
        }
        /// <summary>
        /// 设置BGM音量
        /// </summary>
        /// <param name="value"></param>
        internal void SetBGMVolume(float value)
        {
            BGMEvent.setVolume(value);
        }
        /// <summary>
        /// 暂停BGM
        /// </summary>
        /// <param name="pause"></param>
        internal void PauseBGM(bool pause)
        {
            if (!BGMEvent.isValid()) CheckBGMEventInstance();
            if (BGMEvent.isValid()) BGMEvent.setPaused(pause);
        }
        /// <summary>
        /// 检查BGM实例把之前的释放掉
        /// </summary>
        private void CheckBGMEventInstance()
        {
            if (!string.IsNullOrEmpty(m_CurrBGMAudio))
            {
                if (BGMEvent.isValid())
                {
                    BGMEvent.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                    BGMEvent.release();
                }

                BGMEvent = RuntimeManager.CreateInstance(m_CurrBGMAudio);

                m_CurrBGMVolume = 0;
                SetBGMVolume(m_CurrBGMVolume);

                BGMEvent.start();

                //把音量逐渐变成Max
                m_CurrBGMTimeAction = GameEntry.Time.CreateTimeAction();
                m_CurrBGMTimeAction.Init(0, 0.05f, 100, null, (int loop) =>
                {
                    m_CurrBGMVolume += 0.1f;
                    m_CurrBGMVolume = Mathf.Min(m_CurrBGMVolume, m_CurrBGMMaxVolume);
                    SetBGMVolume(m_CurrBGMVolume);
                    if (m_CurrBGMVolume == m_CurrBGMMaxVolume)
                    {
                        m_CurrBGMTimeAction.Stop();
                    }
                }, null).Run();
            }
        }

        /// <summary>
        /// 停止播放BGM
        /// </summary>
        internal void StopBGM()
        {
            if (BGMEvent.isValid())
            {
                //把音量逐渐变成0 再停止
                m_CurrBGMTimeAction = GameEntry.Time.CreateTimeAction();
                m_CurrBGMTimeAction.Init(0, 0.05f, 100, null, (int loop) =>
                {
                    m_CurrBGMVolume -= 0.1f;
                    m_CurrBGMVolume = Mathf.Max(m_CurrBGMVolume, 0);
                    SetBGMVolume(m_CurrBGMVolume);

                    if (m_CurrBGMVolume == 0)
                    {
                        m_CurrBGMTimeAction.Stop();
                        BGMEvent.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                    }
                }, () =>
                {
                    BGMEvent.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                }).Run();
            }
        }



        /// <summary>
        /// 开始播放BGM
        /// </summary>
        internal void StartBGM()
        {
            BGMEvent.start();
        }

        #endregion

        #region 音效
        /// <summary>
        /// 释放间隔
        /// </summary>
        private int m_ReleaseInterval = 120;
        /// <summary>
        /// 下次释放时间
        /// </summary>
        private float m_NextReleaseTime = 0f;

        /// <summary>
        /// 序号
        /// </summary>
        private int m_Serial = 0;

        /// <summary>
        /// 音效字典
        /// </summary>
        private Dictionary<int, EventInstance> m_CurrAudioEventsDic = new Dictionary<int, EventInstance>();

        /// <summary>
        /// 需要释放的音效编号
        /// </summary>
        private LinkedList<int> m_NeedRemoveList = new LinkedList<int>();

        /// <summary>
        /// 播放音效
        /// </summary>
        internal int PlayAudio(string eventPath, float volume = 1, string parameterName = null, float value = 0, bool is3D = false, Vector3 pos3D = default)
        {
            if (string.IsNullOrEmpty(eventPath)) return -1;

            //生成一个音频
            EventInstance eventInstance = RuntimeManager.CreateInstance(eventPath);
            //设置音量
            eventInstance.setVolume(volume);
            //设置参数
            if (!string.IsNullOrEmpty(parameterName)) eventInstance.setParameterByName(parameterName, value);
            //设置3D音效,设置3D音效位置
            if (is3D) eventInstance.set3DAttributes(pos3D.To3DAttributes());

            eventInstance.start();
            int serialId = m_Serial++;
            m_CurrAudioEventsDic[serialId] = eventInstance;
            return serialId;
        }

        /// <summary>
        /// 设置音效参数
        /// </summary>
        internal void SetParameterForAudio(int serialId, string parameterName, float value)
        {
            EventInstance eventInstance;
            if (m_CurrAudioEventsDic.TryGetValue(serialId, out eventInstance))
            {
                if (eventInstance.isValid()) eventInstance.setParameterByName(parameterName, value);
            }
        }

        /// <summary>
        /// 暂停某个音效
        /// </summary>
        /// <param name="serialId"></param>
        /// <param name="paused"></param>
        /// <returns></returns>
        internal bool PausedAudio(int serialId, bool paused = true)
        {
            EventInstance eventInstance;
            if (m_CurrAudioEventsDic.TryGetValue(serialId, out eventInstance))
            {
                if (eventInstance.isValid())
                {
                    return eventInstance.setPaused(paused) == FMOD.RESULT.OK;
                }
            }
            return false;
        }

        /// <summary>
        /// 停止某个音效
        /// </summary>
        /// <param name="serialId"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        internal bool StopAudio(int serialId, FMOD.Studio.STOP_MODE mode = FMOD.Studio.STOP_MODE.IMMEDIATE)
        {
            EventInstance eventInstance;
            if (m_CurrAudioEventsDic.TryGetValue(serialId, out eventInstance))
            {
                if (eventInstance.isValid())
                {
                    var result = eventInstance.stop(mode);
                    //释放掉
                    eventInstance.release();
                    //从字典中移除掉
                    m_CurrAudioEventsDic.Remove(serialId);
                    return result == FMOD.RESULT.OK;
                }
            }
            return false;
        }

        /// <summary>
        /// 停止所有音效
        /// </summary>
        internal void ShopAllAudio()
        {
            var enumerator = m_CurrAudioEventsDic.GetEnumerator();
            while (enumerator.MoveNext())
            {
                EventInstance eventInstance = enumerator.Current.Value;
                if (eventInstance.isValid())
                {
                    var reselt = eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                    eventInstance.release();
                }
            }
            m_CurrAudioEventsDic.Clear();
        }
        /// <summary>
        /// 释放可释放的音效
        /// </summary>
        private void Release()
        {
            var lst = m_CurrAudioEventsDic.GetEnumerator();
            while (lst.MoveNext())
            {
                EventInstance eventInstance = lst.Current.Value;
                if (!eventInstance.isValid()) continue;

                PLAYBACK_STATE state;
                eventInstance.getPlaybackState(out state);
                //音效的状态停止
                if (state == PLAYBACK_STATE.STOPPED)
                {
                    m_NeedRemoveList.AddLast(lst.Current.Key);
                    eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
                    eventInstance.release();
                }
            }

            LinkedListNode<int> currNode = m_NeedRemoveList.First;
            while (currNode != null)
            {
                LinkedListNode<int> next = currNode.Next;
                int serialId = currNode.Value;
                m_CurrAudioEventsDic.Remove(serialId);
                m_NeedRemoveList.Remove(currNode);
                currNode = next;
            }
        }

        #endregion
    }
}

 

打开调用

关闭调用

 

通过速度控制声音的变幻,模拟汽车声音,混合音效

整个音频文件打一个资源包,初始资源,声音不需要加密

打包打好之后放入CDN的download文件夹下

预加载中

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值