SoundManager.SoundGroup.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. //------------------------------------------------------------
  2. // Game Framework
  3. // Copyright © 2013-2021 loyalsoft. All rights reserved.
  4. // Homepage: http://www.game7000.com/
  5. // Feedback: http://www.game7000.com/
  6. //------------------------------------------------------------
  7. using System.Collections.Generic;
  8. namespace GameFramework.Sound
  9. {
  10. internal sealed partial class SoundManager : GameFrameworkModule, ISoundManager
  11. {
  12. /// <summary>
  13. /// 声音组。
  14. /// </summary>
  15. private sealed class SoundGroup : ISoundGroup
  16. {
  17. private readonly string m_Name;
  18. private readonly ISoundGroupHelper m_SoundGroupHelper;
  19. private readonly List<SoundAgent> m_SoundAgents;
  20. private bool m_AvoidBeingReplacedBySamePriority;
  21. private bool m_Mute;
  22. private float m_Volume;
  23. /// <summary>
  24. /// 初始化声音组的新实例。
  25. /// </summary>
  26. /// <param name="name">声音组名称。</param>
  27. /// <param name="soundGroupHelper">声音组辅助器。</param>
  28. public SoundGroup(string name, ISoundGroupHelper soundGroupHelper)
  29. {
  30. if (string.IsNullOrEmpty(name))
  31. {
  32. throw new GameFrameworkException("Sound group name is invalid.");
  33. }
  34. if (soundGroupHelper == null)
  35. {
  36. throw new GameFrameworkException("Sound group helper is invalid.");
  37. }
  38. m_Name = name;
  39. m_SoundGroupHelper = soundGroupHelper;
  40. m_SoundAgents = new List<SoundAgent>();
  41. }
  42. /// <summary>
  43. /// 获取声音组名称。
  44. /// </summary>
  45. public string Name
  46. {
  47. get
  48. {
  49. return m_Name;
  50. }
  51. }
  52. /// <summary>
  53. /// 获取声音代理数。
  54. /// </summary>
  55. public int SoundAgentCount
  56. {
  57. get
  58. {
  59. return m_SoundAgents.Count;
  60. }
  61. }
  62. /// <summary>
  63. /// 获取或设置声音组中的声音是否避免被同优先级声音替换。
  64. /// </summary>
  65. public bool AvoidBeingReplacedBySamePriority
  66. {
  67. get
  68. {
  69. return m_AvoidBeingReplacedBySamePriority;
  70. }
  71. set
  72. {
  73. m_AvoidBeingReplacedBySamePriority = value;
  74. }
  75. }
  76. /// <summary>
  77. /// 获取或设置声音组静音。
  78. /// </summary>
  79. public bool Mute
  80. {
  81. get
  82. {
  83. return m_Mute;
  84. }
  85. set
  86. {
  87. m_Mute = value;
  88. foreach (SoundAgent soundAgent in m_SoundAgents)
  89. {
  90. soundAgent.RefreshMute();
  91. }
  92. }
  93. }
  94. /// <summary>
  95. /// 获取或设置声音组音量。
  96. /// </summary>
  97. public float Volume
  98. {
  99. get
  100. {
  101. return m_Volume;
  102. }
  103. set
  104. {
  105. m_Volume = value;
  106. foreach (SoundAgent soundAgent in m_SoundAgents)
  107. {
  108. soundAgent.RefreshVolume();
  109. }
  110. }
  111. }
  112. /// <summary>
  113. /// 获取声音组辅助器。
  114. /// </summary>
  115. public ISoundGroupHelper Helper
  116. {
  117. get
  118. {
  119. return m_SoundGroupHelper;
  120. }
  121. }
  122. /// <summary>
  123. /// 增加声音代理辅助器。
  124. /// </summary>
  125. /// <param name="soundHelper">声音辅助器接口。</param>
  126. /// <param name="soundAgentHelper">要增加的声音代理辅助器。</param>
  127. public void AddSoundAgentHelper(ISoundHelper soundHelper, ISoundAgentHelper soundAgentHelper)
  128. {
  129. m_SoundAgents.Add(new SoundAgent(this, soundHelper, soundAgentHelper));
  130. }
  131. /// <summary>
  132. /// 播放声音。
  133. /// </summary>
  134. /// <param name="serialId">声音的序列编号。</param>
  135. /// <param name="soundAsset">声音资源。</param>
  136. /// <param name="playSoundParams">播放声音参数。</param>
  137. /// <param name="errorCode">错误码。</param>
  138. /// <returns>用于播放的声音代理。</returns>
  139. public ISoundAgent PlaySound(int serialId, object soundAsset, PlaySoundParams playSoundParams, out PlaySoundErrorCode? errorCode)
  140. {
  141. errorCode = null;
  142. SoundAgent candidateAgent = null;
  143. foreach (SoundAgent soundAgent in m_SoundAgents)
  144. {
  145. if (!soundAgent.IsPlaying)
  146. {
  147. candidateAgent = soundAgent;
  148. break;
  149. }
  150. if (soundAgent.Priority < playSoundParams.Priority)
  151. {
  152. if (candidateAgent == null || soundAgent.Priority < candidateAgent.Priority)
  153. {
  154. candidateAgent = soundAgent;
  155. }
  156. }
  157. else if (!m_AvoidBeingReplacedBySamePriority && soundAgent.Priority == playSoundParams.Priority)
  158. {
  159. if (candidateAgent == null || soundAgent.SetSoundAssetTime < candidateAgent.SetSoundAssetTime)
  160. {
  161. candidateAgent = soundAgent;
  162. }
  163. }
  164. }
  165. if (candidateAgent == null)
  166. {
  167. errorCode = PlaySoundErrorCode.IgnoredDueToLowPriority;
  168. return null;
  169. }
  170. if (!candidateAgent.SetSoundAsset(soundAsset))
  171. {
  172. errorCode = PlaySoundErrorCode.SetSoundAssetFailure;
  173. return null;
  174. }
  175. candidateAgent.SerialId = serialId;
  176. candidateAgent.Time = playSoundParams.Time;
  177. candidateAgent.MuteInSoundGroup = playSoundParams.MuteInSoundGroup;
  178. candidateAgent.Loop = playSoundParams.Loop;
  179. candidateAgent.Priority = playSoundParams.Priority;
  180. candidateAgent.VolumeInSoundGroup = playSoundParams.VolumeInSoundGroup;
  181. candidateAgent.Pitch = playSoundParams.Pitch;
  182. candidateAgent.PanStereo = playSoundParams.PanStereo;
  183. candidateAgent.SpatialBlend = playSoundParams.SpatialBlend;
  184. candidateAgent.MaxDistance = playSoundParams.MaxDistance;
  185. candidateAgent.DopplerLevel = playSoundParams.DopplerLevel;
  186. candidateAgent.Play(playSoundParams.FadeInSeconds);
  187. return candidateAgent;
  188. }
  189. /// <summary>
  190. /// 停止播放声音。
  191. /// </summary>
  192. /// <param name="serialId">要停止播放声音的序列编号。</param>
  193. /// <param name="fadeOutSeconds">声音淡出时间,以秒为单位。</param>
  194. /// <returns>是否停止播放声音成功。</returns>
  195. public bool StopSound(int serialId, float fadeOutSeconds)
  196. {
  197. foreach (SoundAgent soundAgent in m_SoundAgents)
  198. {
  199. if (soundAgent.SerialId != serialId)
  200. {
  201. continue;
  202. }
  203. soundAgent.Stop(fadeOutSeconds);
  204. return true;
  205. }
  206. return false;
  207. }
  208. /// <summary>
  209. /// 暂停播放声音。
  210. /// </summary>
  211. /// <param name="serialId">要暂停播放声音的序列编号。</param>
  212. /// <param name="fadeOutSeconds">声音淡出时间,以秒为单位。</param>
  213. /// <returns>是否暂停播放声音成功。</returns>
  214. public bool PauseSound(int serialId, float fadeOutSeconds)
  215. {
  216. foreach (SoundAgent soundAgent in m_SoundAgents)
  217. {
  218. if (soundAgent.SerialId != serialId)
  219. {
  220. continue;
  221. }
  222. soundAgent.Pause(fadeOutSeconds);
  223. return true;
  224. }
  225. return false;
  226. }
  227. /// <summary>
  228. /// 恢复播放声音。
  229. /// </summary>
  230. /// <param name="serialId">要恢复播放声音的序列编号。</param>
  231. /// <param name="fadeInSeconds">声音淡入时间,以秒为单位。</param>
  232. /// <returns>是否恢复播放声音成功。</returns>
  233. public bool ResumeSound(int serialId, float fadeInSeconds)
  234. {
  235. foreach (SoundAgent soundAgent in m_SoundAgents)
  236. {
  237. if (soundAgent.SerialId != serialId)
  238. {
  239. continue;
  240. }
  241. soundAgent.Resume(fadeInSeconds);
  242. return true;
  243. }
  244. return false;
  245. }
  246. /// <summary>
  247. /// 停止所有已加载的声音。
  248. /// </summary>
  249. public void StopAllLoadedSounds()
  250. {
  251. foreach (SoundAgent soundAgent in m_SoundAgents)
  252. {
  253. if (soundAgent.IsPlaying)
  254. {
  255. soundAgent.Stop();
  256. }
  257. }
  258. }
  259. /// <summary>
  260. /// 停止所有已加载的声音。
  261. /// </summary>
  262. /// <param name="fadeOutSeconds">声音淡出时间,以秒为单位。</param>
  263. public void StopAllLoadedSounds(float fadeOutSeconds)
  264. {
  265. foreach (SoundAgent soundAgent in m_SoundAgents)
  266. {
  267. if (soundAgent.IsPlaying)
  268. {
  269. soundAgent.Stop(fadeOutSeconds);
  270. }
  271. }
  272. }
  273. }
  274. }
  275. }