Unity的音频管理器

Unity的音频管理器

  public class MusicManager : MonoBehaviour
{
    #region 单例
    private static MusicManager instance = null;
    public static MusicManager Instance
    {
        get
        {
            GameObject musicMgr = GameObject.Find("MusicManager");
            if (musicMgr == null)
            {
                musicMgr = new GameObject("MusicManager");
            }
            if (instance == null)
            {
                instance = musicMgr.GetComponent<MusicManager>();
                if (instance == null)
                {
                    instance = musicMgr.AddComponent<MusicManager>();
                }
            }
            return instance;
        }
    }
    #endregion
    private AudioSource musicAudioSource;//背景音乐的AudioSource

    private List<AudioSource> unusedSoundAudioSourceList;   // 存放可以使用的音频组件

    private List<AudioSource> usedSoundAudioSourceList;     // 存放正在使用的音频组件

    private Dictionary<string, AudioClip> audioClipDict;       // 缓存音频文件

    private float musicVolume = 1; //背景音乐声音

    private float soundVolume = 1; //音效声音

    public string musicVolumePrefs = "MusicVolume";//本地缓存背景音乐的键

    public string soundVolumePrefs = "SoundVolume";//本地缓存音效的键

    private int poolCount = 5;         // AudioSource对象池数量

    void Awake()
    {
        //初始化
        musicAudioSource = gameObject.AddComponent<AudioSource>();
        unusedSoundAudioSourceList = new List<AudioSource>();
        usedSoundAudioSourceList = new List<AudioSource>();
        audioClipDict = new Dictionary<string, AudioClip>();
        DontDestroyOnLoad(this.gameObject);
    }
    void Start() { }
    public void Init()
    {
        // 从本地缓存读取声音音量
        if (PlayerPrefs.HasKey(musicVolumePrefs))
        {
            musicVolume = PlayerPrefs.GetFloat(musicVolumePrefs,1);
        }
        if (PlayerPrefs.HasKey(soundVolumePrefs))
        {
            soundVolume = PlayerPrefs.GetFloat(soundVolumePrefs,1);
        }
    }

    /// <summary>
    /// 播放背景音乐
    /// </summary>
    /// <param name="path">路径</param>
    /// <param name="isLoop">是否循环</param>
    public void PlayMusic(string path, bool isLoop = true)
    {
        //TODO背景音乐的淡入淡出用DOTWEEN
        musicAudioSource.clip = GetAudioClip(path);
        musicAudioSource.clip.LoadAudioData();
        musicAudioSource.loop = isLoop;
        musicAudioSource.volume = musicVolume;
        musicAudioSource.Play();
    }

    /// <summary>
    /// 播放音效
    /// </summary>
    /// <param name="path">音效路径</param>
    /// <param name="func">回调</param>
    public void PlaySound(string path, LuaFunction func)
    {

        AudioSource audioSource = null;
        if (unusedSoundAudioSourceList.Count != 0)
        {
            audioSource = UnusedToUsed();
        }
        else
        {
            AddAudioSource();
            audioSource = UnusedToUsed();
        }
        audioSource.clip = GetAudioClip(path);
        audioSource.clip.LoadAudioData();
        audioSource.volume = soundVolume;
        audioSource.loop = false;
        audioSource.Play();
        StartCoroutine(WaitPlayEnd(audioSource, func));
    }

    /// <summary>
    /// 播放3d音效
    /// </summary>
    /// <param name="path"></param>
    /// <param name="position"></param>
    public void Play3dSound(string path, Vector3 position)
    {
        AudioClip ac = GetAudioClip(path);
        AudioSource.PlayClipAtPoint(ac, position);
    }

    /// <summary>
    /// 设置音量
    /// </summary>
    /// <param name="music">背景音乐的音量</param>
    /// <param name="sound">音效的音量</param>
    public void SetVolume(float music,float sound)
    {
        ChangeMusicVolume(music);
        ChangeSoundVolume(sound);
    }

    /// <summary>
    /// 获取音频文件,获取后会缓存一份
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    private AudioClip GetAudioClip(string path)
    {
        if (audioClipDict.ContainsKey(path) == false)
        {
            AudioClip ac = Resources.Load(path) as AudioClip;
            if (ac == null)
            {
                Debug.LogError("音频在Resource中不存在,请检查音频资源--path" + path);
                return null;
            }
            audioClipDict.Add(path, ac);
        }
        return audioClipDict[path];
    }


    /// <summary>
    /// 添加音频组件
    /// </summary>
    /// <returns></returns>
    private AudioSource AddAudioSource()
    {
        if (unusedSoundAudioSourceList.Count != 0)
        {
            return UnusedToUsed();
        }
        else
        {
            AudioSource audioSource = gameObject.AddComponent<AudioSource>();
            unusedSoundAudioSourceList.Add(audioSource);
            return audioSource;
        }
    }

    /// <summary>
    /// 将未使用的音频组件移至已使用集合里
    /// </summary>
    /// <returns></returns>
    private AudioSource UnusedToUsed()
    {
        AudioSource audioSource = unusedSoundAudioSourceList[0];
        unusedSoundAudioSourceList.RemoveAt(0);
        usedSoundAudioSourceList.Add(audioSource);
        return audioSource;
    }

    /// <summary>
    /// 当播放音效结束后,将其移至未使用集合
    /// </summary>
    /// <param name="audioSource"></param>
    /// <returns></returns>
    IEnumerator WaitPlayEnd(AudioSource audioSource, LuaFunction func)
    {
        yield return new WaitUntil(() => { return !audioSource.isPlaying; });
        UsedToUnused(audioSource);
        if (func != null)
        {
            func.Call();
            func.Dispose();
            func = null;
        }
    }

    /// <summary>
    /// 将使用完的音频组件移至未使用集合里
    /// </summary>
    /// <param name="audioSource"></param>
    private void UsedToUnused(AudioSource audioSource)
    {
        if (usedSoundAudioSourceList.Contains(audioSource))
        {
            usedSoundAudioSourceList.Remove(audioSource);
        }
        if (unusedSoundAudioSourceList.Count >= poolCount)
        {
            Destroy(audioSource);
        }
        else if (audioSource != null && !unusedSoundAudioSourceList.Contains(audioSource))
        {
            unusedSoundAudioSourceList.Add(audioSource);
        }
    }


    /// <summary>
    /// 修改背景音乐音量
    /// </summary>
    /// <param name="volume"></param>
    private void ChangeMusicVolume(float volume)
    {
        musicVolume = volume;
        musicAudioSource.volume = volume;
        PlayerPrefs.SetFloat(musicVolumePrefs, volume);
    }

    /// <summary>
    /// 修改音效音量
    /// </summary>
    /// <param name="volume"></param>
    private void ChangeSoundVolume(float volume)
    {
        soundVolume = volume;
        for (int i = 0; i < unusedSoundAudioSourceList.Count; i++)
        {
            unusedSoundAudioSourceList[i].volume = volume;
        }
        for (int i = 0; i < usedSoundAudioSourceList.Count; i++)
        {
            usedSoundAudioSourceList[i].volume = volume;
        }
        PlayerPrefs.SetFloat(soundVolumePrefs, volume);
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity音频管理器是一个用于在游戏项目中管理音频资源的工具。它的作用是加载、播放、暂停、调节音量等一系列与音频相关的操作。在项目中,我们可以将不同类型的音效资源拖拽到管理器中,然后通过代码调用管理器的接口来对音效进行控制。对于常规的音效操作,管理器已经提供了一些常用的功能,可以满足大部分需求。但对于一些特殊功能,比如在线剪切音频片段、动态调整音乐元素等,可能需要我们自行实现。 Unity中有两个重要的音频组件:AudioListener和AudioSource。通过AudioListener进行监听,通过AudioSource进行音频的播放。因此,使用音频管理器可以统一管理音频的相关操作,提高代码的模块化程度,方便维护和管理音频资源。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【Unity开发小技巧】AudioManager声音管理器](https://blog.csdn.net/qq_37310110/article/details/103311193)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Unity实现音频播放管理器](https://download.csdn.net/download/weixin_38735887/14840003)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [U3D游戏开发框架(四)——音频管理器](https://blog.csdn.net/LLLLL__/article/details/115150281)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值