今天给大家分享下刚刚做的AudioManager
实现了以下功能:
1.同时播放一首背景音乐
2.同时播放N个音效
3.对象池管理AudioSource组件
4.背景音乐的声音淡入淡出
5.调整背景音乐的音量
6.调整音效的音量
7.本地缓存声音音量
8.切换场景不销毁
9.获取播放音效结束回调
10.播放3d音效
使用方法: 直接挂载到空物体上
应该是实现了大部分项目中需要的声音管理类的功能
下面为实现的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
using UnityEngine; using System.Collections; using System.Collections.Generic; using DG.Tweening; using System; public class AudioManager : MonoBehaviour { private static AudioManager instance; public static AudioManager Instance { get { return instance; } } private Dictionary<int, string> audioPathDict; // 存放音频文件路径 private AudioSource musicAudioSource; private List<AudioSource> unusedSoundAudioSourceList; // 存放可以使用的音频组件 private List<AudioSource> usedSoundAudioSourceList; // 存放正在使用的音频组件 private Dictionary<int, AudioClip> audioClipDict; // 缓存音频文件 private float musicVolume = 1; private float soundVolume = 1; private string musicVolumePrefs = "MusicVolume"; private string soundVolumePrefs = "SoundVolume"; private int poolCount = 3; // 对象池数量 void Awake() { DontDestroyOnLoad( this.gameObject ); instance = this; audioPathDict = new Dictionary<int, string>() // 这里设置音频文件路径。需要修改。 TODO { { 1, "AudioClip/Music/MainMenuScene" }, { 2, "AudioClip/Music/BattleScene" }, { 11, "AudioClip/Sound/Sound1"}, { 12, "AudioClip/Sound/Sound2"}, { 13, "AudioClip/Sound/Sound3"}, { 14, "AudioClip/Sound/Sound4"}, { 15, "AudioClip/Sound/Sound5"}, }; musicAudioSource = gameObject.AddComponent<AudioSource>(); unusedSoundAudioSourceList = new List<AudioSource>(); usedSoundAudioSourceList = new List<AudioSource>(); audioClipDict = new Dictionary<int, AudioClip>(); } void Start() { // 从本地缓存读取声音音量 if ( PlayerPrefs.HasKey( musicVolumePrefs ) ) { musicVolume = PlayerPrefs.GetFloat( musicVolumePrefs ); } if ( PlayerPrefs.HasKey( soundVolumePrefs ) ) { musicVolume = PlayerPrefs.GetFloat( soundVolumePrefs ); } } /// <summary> /// 播放背景音乐 /// </summary> /// <param name="id"></param> /// <param name="loop"></param> public void PlayMusic( int id, bool loop = true ) { // 通过Tween将声音淡入淡出 DOTween.To( () => musicAudioSource.volume, value => musicAudioSource.volume = value, 0, 0.5f ).OnComplete( () => { musicAudioSource.clip = GetAudioClip( id ); musicAudioSource.clip.LoadAudioData(); musicAudioSource.loop = loop; musicAudioSource.volume = musicVolume; musicAudioSource.Play(); DOTween.To( () => musicAudioSource.volume, value => musicAudioSource.volume = value, musicVolume, 0.5f ); } ); } /// <summary> /// 播放音效 /// </summary> /// <param name="id"></param> public void PlaySound( int id, Action action = null ) { if ( unusedSoundAudioSourceList.Count != 0 ) { AudioSource audioSource = UnusedToUsed(); audioSource.clip = GetAudioClip( id ); audioSource.clip.LoadAudioData(); audioSource.Play(); StartCoroutine( WaitPlayEnd( audioSource, action ) ); } else { AddAudioSource(); AudioSource audioSource = UnusedToUsed(); audioSource.clip = GetAudioClip( id ); audioSource.clip.LoadAudioData(); audioSource.volume = soundVolume; audioSource.loop = false; audioSource.Play(); StartCoroutine( WaitPlayEnd( audioSource, action ) ); } } /// <summary> /// 播放3d音效 /// </summary> /// <param name="id"></param> /// <param name="position"></param> public void Play3dSound( int id, Vector3 position ) { AudioClip ac = GetAudioClip( id ); AudioSource.PlayClipAtPoint( ac, position ); } /// <summary> /// 当播放音效结束后,将其移至未使用集合 /// </summary> /// <param name="audioSource"></param> /// <returns></returns> IEnumerator WaitPlayEnd( AudioSource audioSource, Action action ) { yield return new WaitUntil( () => { return !audioSource.isPlaying; } ); UsedToUnused( audioSource ); if ( action != null ) { action(); } } /// <summary> /// 获取音频文件,获取后会缓存一份 /// </summary> /// <param name="id"></param> /// <returns></returns> private AudioClip GetAudioClip( int id ) { if ( !audioClipDict.ContainsKey( id ) ) { if ( !audioPathDict.ContainsKey( id ) ) return null; AudioClip ac = Resources.Load( audioPathDict[id] ) as AudioClip; audioClipDict.Add( id, ac ); } return audioClipDict[id]; } /// <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> 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> public void ChangeMusicVolume( float volume ) { musicVolume = volume; musicAudioSource.volume = volume; PlayerPrefs.SetFloat( musicVolumePrefs, volume ); } /// <summary> /// 修改音效音量 /// </summary> /// <param name="volume"></param> public 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { // Use this for initialization void Start () { AudioManager.Instance.PlayMusic( 1 ); AudioManager.Instance.PlaySound( 11, OnSoundPlayEnd ); AudioManager.Instance.ChangeMusicVolume( 0.5f ); AudioManager.Instance.ChangeSoundVolume( 0.5f ); } void OnSoundPlayEnd() { Debug.Log( "音效播放完了" ); } } |
- 本文固定链接: http://www.u3d8.com/?p=1144
- 转载请注明: 网虫虫 在 u3d8.com 发表过