首页 学习日记正文

Unity音频管理模块封装

阿沐 学习日记 2020-04-13 555 0 unity

Unity音频管理模块封装

image.png

1、使用场景:

游戏里播放背景音乐或者音效

2、实现思路:

设置两个空实体作为背景音乐和音效的载体,载体挂载AudioSource组件

背景音乐:只需要一个AudioSource,封装音频播放、暂停、停止功能

音效:可以有多个AudioSource,需要用一个list保存管理【用Mono封装的update帧检测,将播放完的音效移除销毁】

3、具体实现:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 音频管理器
/// </summary>
public class AudioController : SingletonBase<AudioController>
{
    //背景音乐 组件载体
    private GameObject BgAudioObj = null;
    //需要挂载到物体的 音乐组件
    private AudioSource BgSource = null;
    //背景音乐音量设置
    private float BgVolume = 1;

    public AudioController()
    {
        BgAudioObj = new GameObject("BgAudioObj");//初始化载体
        BgSource = BgAudioObj.AddComponent<AudioSource>();//载体添加音频组件
        MonoMgr.GetInstance().addUpdateListener(CheckShortAudio);//监听短音效 移除播放完的短音效
        ShortAudioObj = new GameObject("ShortAudioObj");//初始化音效载体

    }

    #region 背景音乐管理
    /// <summary>
    /// 播放背景音乐
    /// </summary>
    /// <param name="path">背景音乐所在路径</param>
    /// <param name="isLoop">是否循环播放</param>
    public void PlayBgAudio(string path,bool isLoop)
    {
        //如果背景音乐正在播放
        if (BgSource.isPlaying)
        {
            //如果当前播放背景音乐为 我的目标背景音乐 则返回 如果要改背景音乐,则制空音乐,重新加载
            if (BgSource.clip.name == path.Split('/')[path.Split('/').Length - 1])
                return;
            else
                BgSource.clip = null;
        }
        if (BgSource.clip != null && BgSource.clip.name == path.Split('/')[path.Split('/').Length - 1])
        {
            //AudioSource组件已有AudioClip音频,无需加载 直接播放
            BgSource.loop = isLoop;//设置是否循环播放
            BgSource.volume = BgVolume;//设置音量大小
            BgSource.Play();//开始播放
        }
        else
        {
            //AudioSource组件缺少AudioClip音频 需异步加载背景音乐
            ResController.GetInstance().LoadAssetAsync<AudioClip>(path, (clip) =>
            {
                BgSource.clip = clip;
                BgSource.loop = isLoop;//设置是否循环播放
                BgSource.volume = BgVolume;//设置音量大小
                BgSource.Play();//开始播放
            });
        }
       
    }

    //暂停播放背景音乐
    public void PauseBgAudio()
    {
        if(BgSource!=null)
            BgSource.Pause();
    }

    //停止播放背景音乐
    public void StopBgAudio()
    {
        if (BgSource != null)
            BgSource.Stop();
    }

    //设置 背景音乐 音量
    public void setBgAudioVolume(float value)
    {
        BgVolume = value;
    }

    #endregion

    #region 短音效管理
    
    private List<AudioSource> shortAudioList = new List<AudioSource>();//短音效列表 用于管理全部音效
    private float ShortVolume = 1f;//音效音量
    private GameObject ShortAudioObj = null;//音效载体

    //update每帧检测 将播放完的音效 移除列表并删除
    public void CheckShortAudio()
    {
        for (int i = shortAudioList.Count - 1; i >=0; i--)
        {
            if (shortAudioList[i].isPlaying == false)
            {
                GameObject.Destroy(shortAudioList[i]);//销毁音效
                shortAudioList.RemoveAt(i);//音效列表移除
            }
        }
    }
    //播放短音效
    public void PlayShortAudio(string name,bool isLoop,UnityAction<AudioSource> callBack=null)
    {
        //每次播放的时候 需要添加 音频组件 AudioSource
        AudioSource aClipSource = ShortAudioObj.AddComponent<AudioSource>();
        //异步加载音效
        ResController.GetInstance().LoadAssetAsync<AudioClip>(name, (clip) => {
            aClipSource.clip = clip;//绑定音效
            aClipSource.volume = ShortVolume;//设置音效音量
            aClipSource.loop = isLoop;//是否循环播放
            aClipSource.Play();
            shortAudioList.Add(aClipSource);//添加至音效列表
        });
        //执行自定义回调函数
        if (callBack != null)
            callBack(aClipSource);
    }

    //暂停短音效
    public void PauseShortAudio(AudioSource source)
    {
        if (shortAudioList.Contains(source))
        {
            source.Pause();//音效暂停
        }
    }

    //停止播放短音效
    public void StopShortAudio(AudioSource source)
    {
        //判断音效列表是否存在该音效
        if (shortAudioList.Contains(source))
        {
            shortAudioList.Remove(source);//音效列表移除该音效
            source.Stop();//音效暂停
            GameObject.Destroy(source);//音效销毁
        }
    }

    //设置 音效 音量
    public void setShortAudioVolume(float value)
    {
        ShortVolume = value;
        for (int i = 0; i < shortAudioList.Count; i++)
        {
            shortAudioList[i].volume = value;//将音效列表全部音效设置音量
        }
    }

    #endregion
}

测试:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MusicTest : MonoBehaviour {

    void OnGUI()
    {
        if (GUI.Button(new Rect(0, 100, 100, 100), "播放背景音乐"))
        {
            Debug.Log("播放音乐");
            AudioController.GetInstance().setBgAudioVolume(0.5f);
            AudioController.GetInstance().PlayBgAudio("Music/BgAudio/happy",true);
        }
        if (GUI.Button(new Rect(0, 200, 100, 100), "暂停背景音乐"))
        {
            Debug.Log("暂停播放");
            AudioController.GetInstance().PauseBgAudio();
        }
        if (GUI.Button(new Rect(0, 300, 100, 100), "停止背景音乐"))
        {
            Debug.Log("停止播放");
            AudioController.GetInstance().StopBgAudio();
        }

        if (GUI.Button(new Rect(100, 100, 100, 100), "贪吃蛇背景音乐"))
        {
            Debug.Log("贪吃蛇背景音乐");
            AudioController.GetInstance().setBgAudioVolume(1f);
            AudioController.GetInstance().PlayBgAudio("Music/BgAudio/tcs", true);
        }

        if (GUI.Button(new Rect(100, 200, 100, 100), "音效"))
        {
            Debug.Log("音效播放");
            AudioController.GetInstance().PlayShortAudio("Music/ShortAudio/start",false);
        }
    }
}

效果:

image.png

打赏

评论

Music