【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]