AudioManager.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. public class AudioManager : MonoSingleton<AudioManager>
  6. {
  7. #region 背景音乐的音乐名称常量
  8. /// <summary>
  9. /// 背景音乐
  10. /// </summary>
  11. public const string MainBackMusic = "Lonely Mountain";
  12. /// <summary>
  13. /// 登录背景音乐
  14. /// </summary>
  15. public const string LoginBackMusic = "Black Knight";
  16. /// <summary>
  17. /// 战斗背景音乐
  18. /// </summary>
  19. //public const string BattleBackMusic = "Blue Stahli-Overklock";
  20. public const string BattleBackMusic = "Dawn of the Apocalypse";
  21. /// <summary>
  22. /// 过场动画背景音乐
  23. /// </summary>
  24. public const string LoadingBackMusic = "Black Knight";
  25. /// <summary>
  26. /// PVP背景音乐
  27. /// </summary>
  28. public const string PVPBackMusic = "Music_PVP_B1";
  29. /// <summary>
  30. /// 关卡背景音乐
  31. /// </summary>
  32. public const string GateBackMusic = "Lonely Mountain";
  33. #endregion
  34. #region 特殊音效
  35. /// <summary>
  36. /// 战斗失败
  37. /// </summary>
  38. public const string BattleSepcial_LoseSound = "Music_Battle_Lose";
  39. /// <summary>
  40. /// 战斗胜利
  41. /// </summary>
  42. public const string BattleSepcial_WinSound = "Music_Battle_Win";
  43. /// <summary>
  44. /// boss出现音效
  45. /// </summary>
  46. public const string BattleSepcial_BossDisplaySound = "The Enemy";
  47. /// <summary>
  48. /// 战斗开始<四个字>特效 音效
  49. /// </summary>
  50. public const string BattleSepcial_StartFightSound = "Music_Battle_Start";
  51. /// <summary>
  52. /// 战斗——连击准备开始特效 音效
  53. /// </summary>
  54. public const string BattleSepcial_LianJISound = "Music_Battle_Lianji";
  55. #endregion
  56. private const string AudioContainer_HeroAnimation_Display = "AudioContainer_HeroAnimation_Display";
  57. private const string AudioContainer_HeroAnimation_Attack = "AudioContainer_HeroAnimation_Attack";
  58. private const string AudioContainer_HeroAnimation_BeAttack = "AudioContainer_HeroAnimation_BeAttack";
  59. /// <summary>
  60. /// 背景音乐容器
  61. /// </summary>
  62. private const string AudioContainer_Music = "AudioContainer_Music";
  63. /// <summary>
  64. /// UI音效容器
  65. /// </summary>
  66. private const string AudioContainer_UISound = "AudioContainer_UISound";
  67. /// <summary>
  68. /// UI音效容器
  69. /// </summary>
  70. private const string AudioContainer_Skill = "AudioContainer_Skill";
  71. #region
  72. /// <summary>
  73. /// 资源
  74. /// </summary>
  75. public Dictionary<string, AudioClip> mAudioResDic = new Dictionary<string, AudioClip>();
  76. /// <summary>
  77. /// 加载资源
  78. /// </summary>
  79. /// <param name="bundleName"> 资源包的名称 </param>
  80. /// <param name="ac"> 加载完后执行的回调 </param>
  81. private void LoadAudioBundleRes(string bundleName, Action ac)
  82. {
  83. ResourceHelper.Instance.LoadAssetBundle(bundleName, (AssetBundle bundle) =>
  84. {
  85. if (null != bundle)
  86. {
  87. GameObject audioObj = bundle.LoadAsset<GameObject>(bundleName);
  88. AudioContainer audioContainer = audioObj.GetComponent<AudioContainer>();
  89. foreach (var audio in audioContainer.mAudioList)
  90. {
  91. mAudioResDic[audio.name] = audio;
  92. }
  93. }
  94. });
  95. }
  96. /// <summary>
  97. /// 获取图标
  98. /// </summary>
  99. /// <param name="audioBundleContainer">容器bundle名称</param>
  100. /// <param name="audioName"> 图标的名称 </param>
  101. /// <param name="callBack">赋值成功后回调</param>
  102. public void GetAudioClip(string audioBundleContainer, string audioName, Action<AudioClip> callBack)
  103. {
  104. if (mAudioResDic.ContainsKey(audioName) && mAudioResDic[audioName] != null)
  105. {
  106. if (callBack != null)
  107. {
  108. callBack(mAudioResDic[audioName]);
  109. }
  110. }
  111. else
  112. {
  113. LoadAudioBundleRes(audioBundleContainer, () =>
  114. {
  115. if (mAudioResDic.ContainsKey(audioName))
  116. {
  117. if (callBack != null)
  118. {
  119. callBack(mAudioResDic[audioName]);
  120. }
  121. }
  122. else
  123. {
  124. //LogHelper.Log("null--->" + audioName);
  125. callBack(null);
  126. }
  127. });
  128. }
  129. }
  130. #endregion
  131. /// <summary>
  132. /// 背景音乐与音效的比例
  133. /// </summary>
  134. public const float mRatio = 0.44f;
  135. /// <summary>
  136. /// 背景声音音量
  137. /// </summary>
  138. public float _musicVolumeSize;
  139. /// <summary>
  140. /// 音效音量大小
  141. /// </summary>
  142. public float effectVolumeSize;
  143. /// <summary>
  144. /// 背景声音音量
  145. /// </summary>
  146. public float MusicVolumeSize
  147. {
  148. get { return _musicVolumeSize * mRatio; }
  149. }
  150. /// <summary>
  151. /// 已加载的AssetBundle
  152. /// </summary>
  153. private Dictionary<string, GameObject> musicAudioDic = new Dictionary<string, GameObject>();
  154. /// <summary>
  155. /// 已加载的AssetBundle
  156. /// </summary>
  157. private Dictionary<string, GameObject> _heroSoundAudioDic = new Dictionary<string, GameObject>();
  158. private void Start()
  159. {
  160. mAudioResDic.Clear();
  161. //读取本地存储的音乐音效的音量设置
  162. _musicVolumeSize = 1.0f * LocalSettings.MusicVolume / 2 / 100;
  163. effectVolumeSize = 1.0f * LocalSettings.EffectVolume * 3 / 100;
  164. }
  165. /// <summary>
  166. /// 初始化
  167. /// </summary>
  168. protected override void OnAwake()
  169. {
  170. // 切换关卡时不删除
  171. //DontDestroyOnLoad(this);
  172. if (this.GetComponent<AudioListener>() == null)
  173. {
  174. this.gameObject.AddComponent<AudioListener>();
  175. }
  176. }
  177. #region 音乐音效文件的卸载播放对象
  178. /// <summary>
  179. /// 卸载某个音效 gameobject
  180. /// </summary>
  181. /// <param name="name">名称</param>
  182. /// <returns>是否卸载成功</returns>
  183. public bool UnloadHeroSoundAudioObject(string heroModelId)
  184. {
  185. if (_heroSoundAudioDic.ContainsKey(heroModelId))
  186. {
  187. Destroy(_heroSoundAudioDic[heroModelId]);
  188. _heroSoundAudioDic.Remove(heroModelId);
  189. return true;
  190. }
  191. else
  192. {
  193. LogHelper.LogWarning("角色音效卸载失败_" + heroModelId);
  194. }
  195. return false;
  196. }
  197. /// <summary>
  198. /// 卸载某个音效 gameobject
  199. /// </summary>
  200. /// <param name="name">名称</param>
  201. /// <returns>是否卸载成功</returns>
  202. public bool UnloadMusicAudioObject(string name)
  203. {
  204. if (musicAudioDic.ContainsKey(name))
  205. {
  206. Destroy(musicAudioDic[name]);
  207. musicAudioDic.Remove(name);
  208. return true;
  209. }
  210. else
  211. {
  212. LogHelper.LogWarning("音效卸载失败_" + name);
  213. }
  214. return false;
  215. }
  216. /// <summary>
  217. /// 清理所有音效
  218. /// </summary>
  219. public void DestoryAllMusicAudioObject()
  220. {
  221. List<string> KeyList = new List<string>(musicAudioDic.Keys);
  222. for (int i = 0; i < KeyList.Count; i++)
  223. {
  224. UnloadMusicAudioObject(KeyList[i]);
  225. }
  226. }
  227. #endregion
  228. /// <summary>
  229. ///
  230. /// </summary>
  231. private string _curBackMusicResName = "";
  232. #region
  233. /// <summary>
  234. /// 关闭某个背景音乐的播放
  235. /// </summary>
  236. /// <param name="soundResName"></param>
  237. public void StopGameBackMusicPlay(string soundResName, float ts = 0.1f)
  238. {
  239. if (musicAudioDic.ContainsKey(soundResName))
  240. {
  241. GameObject _audioBack = musicAudioDic[soundResName];
  242. AudioSource tempSource = _audioBack.GetComponent<AudioSource>();
  243. tempSource.volume = 0;
  244. tempSource.Stop();
  245. //////////键值对儿的形式保存iTween所用到的参数
  246. ////////Hashtable args = new Hashtable();
  247. //////////音量
  248. ////////args.Add("volume", 0);
  249. //////////变化的时间
  250. ////////args.Add("time", ts);
  251. //////////播放结束时调用,参数和上面类似
  252. ////////////args.Add("oncomplete", "OnAudioPlayEnd");
  253. ////////////args.Add("oncompleteparams", soundResName);
  254. ////////////args.Add("oncompletetarget", _audioBack);
  255. ////////iTween.AudioTo(_audioBack, args);
  256. }
  257. }
  258. /// <summary>
  259. /// 播放背景音乐
  260. /// 渐变出现
  261. /// </summary>
  262. /// <param name="soundResName">音乐资源</param>
  263. /// <param name="ts">音乐播放声音正常的时间</param>
  264. private void PlayMusic(string soundResName, float ts)
  265. {
  266. if (string.IsNullOrEmpty(soundResName))
  267. {
  268. return;
  269. }
  270. if (musicAudioDic.ContainsKey(soundResName))
  271. {
  272. GameObject _audioBack = musicAudioDic[soundResName];
  273. AudioSource xxx = _audioBack.GetComponent<AudioSource>();
  274. if (soundResName != _curBackMusicResName)
  275. {
  276. xxx.Stop();
  277. xxx.volume = 0;
  278. //////iTween.AudioTo(_audioBack, 0, 0, 0.5f);
  279. }
  280. else
  281. {
  282. xxx.Play();
  283. xxx.volume = MusicVolumeSize;
  284. //////iTween.AudioTo(_audioBack, MusicVolumeSize, 0, 0.5f);
  285. }
  286. }
  287. else
  288. {
  289. GetAudioClip(AudioContainer_Music, soundResName, aClip =>
  290. {
  291. if (aClip != null)
  292. {
  293. GameObject _audioBack = new GameObject(soundResName);
  294. _audioBack.AddComponent<GameBackAudio>();
  295. _audioBack.transform.SetParent(this.transform);
  296. AudioSource xxx = _audioBack.GetComponent<AudioSource>();
  297. xxx.clip = aClip;
  298. xxx.loop = true;
  299. xxx.pitch = 1;
  300. xxx.volume = 0;
  301. xxx.Play();
  302. musicAudioDic.Add(soundResName, _audioBack);
  303. //键值对儿的形式保存iTween所用到的参数
  304. Hashtable args = new Hashtable();
  305. if (soundResName == _curBackMusicResName)
  306. {
  307. //音量
  308. args.Add("volume", MusicVolumeSize);
  309. }
  310. else
  311. {
  312. //音量
  313. args.Add("volume", 0);
  314. }
  315. //音调
  316. args.Add("pitch", 1);
  317. //变化的时间
  318. args.Add("time", ts);
  319. iTween.AudioTo(_audioBack, args);
  320. }
  321. });
  322. }
  323. }
  324. /// <summary>
  325. /// 背景音乐的过渡
  326. /// </summary>
  327. /// <param name="newBackMusic">新的背景音乐名称</param>
  328. /// <param name="delayTime">背景音乐的播放延迟时间</param>
  329. public void ChangeGameBackMusic(string newBackMusic, float delayTime)
  330. {
  331. if (string.IsNullOrEmpty(newBackMusic))
  332. {
  333. return;
  334. }
  335. if (_curBackMusicResName != newBackMusic)
  336. {
  337. if (!string.IsNullOrEmpty(_curBackMusicResName))
  338. {
  339. StopGameBackMusicPlay(_curBackMusicResName, delayTime);
  340. }
  341. else
  342. {
  343. delayTime = 0.1f;
  344. }
  345. _curBackMusicResName = newBackMusic;
  346. PlayMusic(_curBackMusicResName, delayTime);
  347. }
  348. else
  349. {
  350. }
  351. }
  352. /// <summary>
  353. /// 改变背景音乐的 音量
  354. /// </summary>
  355. /// <param name="_vol"></param>
  356. public void ChangeBackMusicVolume(float _vol)
  357. {
  358. _musicVolumeSize = _vol;
  359. foreach (string soundResName in musicAudioDic.Keys)
  360. {
  361. GameObject _audioBack = musicAudioDic[soundResName];
  362. //键值对儿的形式保存iTween所用到的参数
  363. Hashtable args = new Hashtable();
  364. //音量
  365. args.Add("volume", MusicVolumeSize);
  366. //音调
  367. args.Add("pitch", 1);
  368. //变化的时间
  369. args.Add("time", 0.01f);
  370. iTween.AudioTo(_audioBack, args);
  371. }
  372. }
  373. #endregion
  374. /// <summary>
  375. /// 改变音效的 音量
  376. /// </summary>
  377. /// <param name="_vol"></param>
  378. public void ChangeEffectMusicVolume(float _vol)
  379. {
  380. effectVolumeSize = _vol;
  381. }
  382. /// <summary>
  383. /// 技能的音效播放
  384. /// 技能音效一个音效文件一个bundle文件
  385. /// </summary>
  386. /// <param name="resName">技能音效的 资源名</param>
  387. public void PlayUISoundEffect(string soundName)
  388. {
  389. if (string.IsNullOrEmpty(soundName))
  390. {
  391. return;
  392. }
  393. GetAudioClip(AudioContainer_UISound, soundName, aClip =>
  394. {
  395. if (aClip != null)
  396. {
  397. GameObject _effectObj = new GameObject(soundName);
  398. _effectObj.transform.SetParent(this.transform);
  399. AudioSource xxx = _effectObj.AddComponent<AudioSource>();
  400. xxx.clip = aClip;
  401. xxx.loop = false;
  402. xxx.pitch = 1;
  403. xxx.volume = effectVolumeSize;
  404. xxx.PlayOneShot(aClip);
  405. Destroy(_effectObj, aClip.length + 1.0f);
  406. }
  407. });
  408. }
  409. /// <summary>
  410. /// 技能的音效播放
  411. /// 技能音效一个音效文件一个bundle文件
  412. /// </summary>
  413. /// <param name="resName">技能音效的 资源名</param>
  414. public void PlaySkillSoundEffect(string resName)
  415. {
  416. //LogHelper.LogError("PlaySkillSoundEffect::::" + resName);
  417. if (string.IsNullOrEmpty(resName))
  418. {
  419. return;
  420. }
  421. GetAudioClip(AudioManager.AudioContainer_Skill, resName, aClip =>
  422. {
  423. if (aClip != null)
  424. {
  425. GameObject _effectObj = new GameObject(resName);
  426. _effectObj.transform.SetParent(this.transform);
  427. AudioSource xxx = _effectObj.AddComponent<AudioSource>();
  428. xxx.clip = aClip;
  429. xxx.loop = false;
  430. xxx.pitch = 1;
  431. xxx.volume = effectVolumeSize;
  432. xxx.PlayOneShot(aClip);
  433. Destroy(_effectObj, aClip.length + 1.0f);
  434. }
  435. });
  436. }
  437. /// <summary>
  438. /// 播放玩家的声音
  439. /// 因为玩家的声音存在多次播放的可能
  440. /// </summary>
  441. /// <param name="heroModelId">模型ID</param>
  442. /// <param name="soundResName">声音</param>
  443. public void PlayHeroSound(string heroModelId, string soundResName, ESoundType soundType)
  444. {
  445. if (string.IsNullOrEmpty(soundResName))
  446. {
  447. return;
  448. }
  449. if (_heroSoundAudioDic.ContainsKey(heroModelId))
  450. {
  451. }
  452. else
  453. {
  454. GameObject _effectObj = new GameObject(heroModelId);
  455. _effectObj.transform.SetParent(this.transform);
  456. _effectObj.AddComponent<AudioSource>();
  457. _heroSoundAudioDic.Add(heroModelId, _effectObj);
  458. }
  459. string containerName = string.Empty;
  460. switch (soundType)
  461. {
  462. case ESoundType.HERO_SOUND_ATTACK:
  463. containerName = AudioManager.AudioContainer_HeroAnimation_Attack;
  464. break;
  465. case ESoundType.HERO_SOUND_DISPLAY:
  466. containerName = AudioManager.AudioContainer_HeroAnimation_Display;
  467. break;
  468. case ESoundType.HERO_SOUND_BEATTACK:
  469. containerName = AudioManager.AudioContainer_HeroAnimation_BeAttack;
  470. break;
  471. }
  472. if (!string.IsNullOrEmpty(containerName))
  473. {
  474. GetAudioClip(containerName, soundResName, aClip =>
  475. {
  476. if (aClip != null)
  477. {
  478. GameObject _audioBack = _heroSoundAudioDic[heroModelId];
  479. AudioSource xxx = _audioBack.GetComponent<AudioSource>();
  480. xxx.clip = aClip;
  481. xxx.loop = false;
  482. xxx.pitch = 1;
  483. xxx.volume = effectVolumeSize;
  484. if (!xxx.isPlaying)
  485. {
  486. xxx.Play();
  487. }
  488. }
  489. });
  490. }
  491. }
  492. }
  493. public enum ESoundType
  494. {
  495. SKILL,
  496. UI,
  497. ////HERO_NORMAL,
  498. ////HERO_ATTACK,
  499. ////HERO_SKILL,
  500. ////HERO_CRICAL,
  501. ////HERO_ANIMATION_IDLE,
  502. ////HERO_ANIMATION_IDLE1,
  503. ////HERO_ANIMATION_ATTACK,
  504. HERO_SOUND_DISPLAY,
  505. HERO_SOUND_ATTACK,
  506. HERO_SOUND_BEATTACK
  507. }
  508. /// <summary>
  509. ///
  510. /// </summary>
  511. public enum ESoundUIType
  512. {
  513. ToggleBtn,
  514. NormalBtn,
  515. CloseBtn
  516. }