AudioManager.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. using System;
  2. using System.Collections.Generic;
  3. using Fort23.Core;
  4. using Fort23.UTool;
  5. using UnityEngine;
  6. using UnityEngine.Audio;
  7. using Utility;
  8. using Object = UnityEngine.Object;
  9. namespace Core.Audio
  10. {
  11. public class AudioManager : Singleton<AudioManager>
  12. {
  13. private GameObject _root;
  14. public AudioMixerGroup AudioMixerGroup;
  15. private Map<string, AudioBundleInfo> _allAduionBundleInfos = new Map<string, AudioBundleInfo>();
  16. private Queue<AudioSourcePool> _audioSourcePools = new Queue<AudioSourcePool>();
  17. private Map<string, List<AudioSourcePool>> _currPlayAudio = new Map<string, List<AudioSourcePool>>();
  18. private List<string> _bgmQueue = new List<string>();
  19. private AudioSourcePool _currBgm;
  20. private List<string> _audion = new List<string>();
  21. public float AudionVolume
  22. {
  23. get => _audionVolume;
  24. }
  25. public float BgmVolume
  26. {
  27. get => _bgmVolume;
  28. }
  29. private float _audionVolume = 1;
  30. private float _bgmVolume = 1;
  31. public AudioManager()
  32. {
  33. // UIAudio.AudioPlayManager = this;
  34. _root = new GameObject();
  35. _root.name = "audio";
  36. AudioListener audioListener = GameObject.FindObjectOfType<AudioListener>();
  37. if (audioListener == null)
  38. {
  39. _root.AddComponent<AudioListener>();
  40. }
  41. Object.DontDestroyOnLoad(_root);
  42. }
  43. /// <summary>
  44. /// 设置音效音量
  45. /// </summary>
  46. /// <param name="value"></param>
  47. public void SetAudioValue(float value)
  48. {
  49. _audionVolume = value;
  50. for (_currPlayAudio.Begin(); _currPlayAudio.Next();)
  51. {
  52. for (int i = 0; i < _currPlayAudio.Value.Count; i++)
  53. {
  54. _currPlayAudio.Value[i].Setvolume();
  55. }
  56. }
  57. }
  58. /// <summary>
  59. /// 设置背景音乐音量
  60. /// </summary>
  61. /// <param name="value"></param>
  62. public void SetBgmValue(float value)
  63. {
  64. _bgmVolume = value;
  65. // for (_currPlayAudio.Begin(); _currPlayAudio.Next();)
  66. // {
  67. // for (int i = 0; i < _currPlayAudio.Value.Count; i++)
  68. // {
  69. // _currPlayAudio.Value[i].Setvolume();
  70. // }
  71. // }
  72. _currBgm?.Setvolume();
  73. }
  74. public async CTask Init()
  75. {
  76. }
  77. public async CTask InitMainAudio()
  78. {
  79. string config = "MainAudio.asset";
  80. AssetHandle assetHandle =
  81. await AssetBundleLoadManager.Instance.LoadAssetAsyncTask<AudionSettingConfig>(config);
  82. await LoadAudio(assetHandle.AssetObject<AudionSettingConfig>());
  83. }
  84. public async CTask LoadAudio(AudionSettingConfig audionSettingConfig)
  85. {
  86. CTaskAwaitBuffer cTaskAwaitBuffer = new CTaskAwaitBuffer();
  87. for (int i = 0; i < audionSettingConfig.configs.Count; i++)
  88. {
  89. CTask cTask = LoadAudio(audionSettingConfig.configs[i]);
  90. cTaskAwaitBuffer.AddTask(cTask);
  91. }
  92. await cTaskAwaitBuffer.WaitAll();
  93. }
  94. public void RemoveAudio(AudionSettingConfig audionSettingConfig)
  95. {
  96. for (int i = 0; i < audionSettingConfig.configs.Count; i++)
  97. {
  98. AudionSettingConfig.AudionConfig audionConfig = audionSettingConfig.configs[i];
  99. if (_allAduionBundleInfos.TryGetValue(audionConfig.audionClipName, out AudioBundleInfo abi))
  100. {
  101. if (_currPlayAudio.TryGetValue(audionConfig.audionClipName,
  102. out List<AudioSourcePool> audioSourcePool))
  103. {
  104. for (int j = 0; j < audioSourcePool.Count; j++)
  105. {
  106. audioSourcePool[i].Finish();
  107. }
  108. }
  109. abi.Dispose();
  110. _allAduionBundleInfos.Remove(audionConfig.audionClipName);
  111. }
  112. }
  113. }
  114. public async CTask LoadAudio(AudionSettingConfig.AudionConfig audionConfig)
  115. {
  116. await GetAduionBundleInfo(audionConfig.audionClipName, audionConfig.volume);
  117. }
  118. public async CTask<AudioBundleInfo> GetAduionBundleInfo(string audionName, float volume = 1)
  119. {
  120. // if (audionName.Contains('.'))
  121. // {
  122. // audionName = audionName.Split('.')[0];
  123. // }
  124. if (_allAduionBundleInfos.TryGetValue(audionName, out AudioBundleInfo abi))
  125. {
  126. return abi;
  127. }
  128. AudioBundleInfo audioBundleInfo = new AudioBundleInfo(audionName, volume);
  129. _allAduionBundleInfos.Add(audionName, audioBundleInfo);
  130. await audioBundleInfo.GetAudioClip();
  131. return audioBundleInfo;
  132. }
  133. public void Recycle(AudioSourcePool audioSourcePool)
  134. {
  135. if (!_audioSourcePools.Contains(audioSourcePool))
  136. {
  137. _audioSourcePools.Enqueue(audioSourcePool);
  138. }
  139. if (_currPlayAudio.TryGetValue(audioSourcePool.CurrPlayName, out List<AudioSourcePool> audioSourcePools))
  140. {
  141. audioSourcePools.Remove(audioSourcePool);
  142. }
  143. }
  144. private AudioSourcePool GetAudioSourcePool()
  145. {
  146. if (_audioSourcePools.Count <= 0)
  147. {
  148. AudioSourcePool audioSourcePool = new AudioSourcePool();
  149. audioSourcePool.Init(_root.transform);
  150. return audioSourcePool;
  151. }
  152. AudioSourcePool asp = _audioSourcePools.Dequeue();
  153. return asp;
  154. }
  155. public void Stop(string audionName)
  156. {
  157. if (_currPlayAudio.TryGetValue(audionName, out List<AudioSourcePool> asp))
  158. {
  159. for (int i = 0; i < asp.Count; i++)
  160. {
  161. AudioSourcePool a = asp[i];
  162. a.Finish();
  163. i--;
  164. }
  165. }
  166. }
  167. public async void PlayBGM(string bgmName)
  168. {
  169. if (_currBgm != null && _currBgm.CurrPlayName != null && _currBgm.CurrPlayName.Equals(bgmName))
  170. {
  171. return;
  172. }
  173. if (_currBgm != null && _currBgm.IsPlay)
  174. {
  175. _bgmQueue.Add(_currBgm.CurrPlayName);
  176. }
  177. AudioBundleInfo audioBundleInfo = await GetAduionBundleInfo(bgmName);
  178. AssetHandle audioClip = await audioBundleInfo.GetAudioClip();
  179. if (_currBgm == null)
  180. {
  181. _currBgm = GetAudioSourcePool();
  182. }
  183. _currBgm.Play(bgmName, true, audioClip, true, audioBundleInfo._volume);
  184. }
  185. public void PauseBGM()
  186. {
  187. if (_currBgm != null)
  188. {
  189. _currBgm.Pause();
  190. }
  191. }
  192. public void UnPauseBGM()
  193. {
  194. if (_currBgm != null)
  195. {
  196. _currBgm.UnPause();
  197. }
  198. }
  199. public async void StopBGM(string bgmName)
  200. {
  201. if (_currBgm == null || _currBgm._currPlayName == null)
  202. {
  203. return;
  204. }
  205. if (_currBgm.CurrPlayName.Equals(bgmName))
  206. {
  207. _currBgm.Stop();
  208. if (_bgmQueue.Count > 0)
  209. {
  210. string nextBgmName = _bgmQueue[^1];
  211. _bgmQueue.RemoveAt(_bgmQueue.Count - 1);
  212. PlayBGM(nextBgmName);
  213. }
  214. return;
  215. }
  216. if (_bgmQueue.Count > 0)
  217. {
  218. for (int i = _bgmQueue.Count - 1; i >= 0; i--)
  219. {
  220. if (_bgmQueue[i].Equals(bgmName))
  221. {
  222. _bgmQueue.RemoveAt(i);
  223. }
  224. }
  225. }
  226. }
  227. public async CTask<AudioSourcePool> PlayAudio(string audionName, bool isLoop = false, float speed = 1)
  228. {
  229. if (string.IsNullOrEmpty(audionName))
  230. {
  231. return null;
  232. }
  233. if (audionName.IndexOf(".", StringComparison.Ordinal) < 0)
  234. {
  235. audionName += ".wav";
  236. }
  237. using (await CoroutineLockComponent.Instance.Wait(audionName))
  238. {
  239. if (_currPlayAudio.TryGetValue(audionName, out List<AudioSourcePool> asp))
  240. {
  241. for (int i = 0; i < asp.Count; i++)
  242. {
  243. AudioSourcePool a = asp[i];
  244. float t = a.GetPlayTime();
  245. if (t > 0 && t < 0.05f)
  246. {
  247. return null;
  248. }
  249. a.Setvolume(a.AudioVolume - 0.33f);
  250. if (a.AudioVolume <= 0)
  251. {
  252. a.Finish();
  253. i--;
  254. }
  255. }
  256. // if (asp.Progress() < 0.2)
  257. // {
  258. // return null;
  259. // }
  260. //
  261. // asp.Finish();
  262. }
  263. else
  264. {
  265. asp = new List<AudioSourcePool>();
  266. _currPlayAudio.Add(audionName, asp);
  267. }
  268. AudioBundleInfo audioBundleInfo = await GetAduionBundleInfo(audionName);
  269. AssetHandle audioClip = await audioBundleInfo.GetAudioClip();
  270. if (audioClip == null)
  271. {
  272. return null;
  273. }
  274. AudioSourcePool audioSourcePool = GetAudioSourcePool();
  275. audioSourcePool.Play(audionName, false, audioClip, isLoop, audioBundleInfo._volume, speed);
  276. asp.Add(audioSourcePool);
  277. return audioSourcePool;
  278. }
  279. }
  280. public void Play(string audionName, bool isLoop)
  281. {
  282. PlayAudio(audionName, isLoop);
  283. }
  284. public void TimeLinePlayAudio(string audioName, bool isLoop, float speed)
  285. {
  286. PlayAudio(audioName, isLoop);
  287. }
  288. }
  289. }