SoundManager.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. [Serializable]
  6. public class SoundConfig
  7. {
  8. public SoundEvent soundEvent;
  9. public AudioClip clip;
  10. public float volume = 1;
  11. public float pitch = 1;
  12. }
  13. public class SoundManager : MonoBehaviour
  14. {
  15. #region Unity Singleton
  16. private static SoundManager _instance;
  17. public static SoundManager Instance
  18. {
  19. get
  20. {
  21. if (_instance == null)
  22. {
  23. _instance = FindObjectOfType(typeof(SoundManager)) as SoundManager;
  24. if (_instance == null)
  25. {
  26. AVDebug.LogError(string.Format("No gameObject with {0} component exists. Make sure to create a gameObject with {0} component", new System.Diagnostics.StackFrame().GetMethod().DeclaringType));
  27. }
  28. }
  29. return _instance;
  30. }
  31. }
  32. void Awake()
  33. {
  34. if (_instance != null && _instance != this)
  35. {
  36. AVDebug.LogWarning(string.Format("{0} Instance already exists on another gameObject. Destroying this gameObject {1}", this.GetType().Name, gameObject.name));
  37. Destroy(gameObject);
  38. return;
  39. }
  40. _instance = this;
  41. DontDestroyOnLoad(gameObject);
  42. audioSources = new AudioSource[soundConfigs.Length];
  43. sfxVolume = PlayerPrefs.GetFloat("sfxVolume", 1);
  44. Debug.Log(PlayerPrefs.GetFloat("musicVolume"));
  45. musicVolume = PlayerPrefs.GetFloat("musicVolume", GameConstants.MUSIC_VOLUME);
  46. }
  47. #endregion
  48. #region soundRecording
  49. enum SoundActionType
  50. {
  51. Play,
  52. Stop,
  53. Loop,
  54. StopLoop
  55. }
  56. struct SoundAction
  57. {
  58. public SoundEvent soundEvent;
  59. public SoundActionType actionType;
  60. public float delay;
  61. }
  62. List<SoundAction> soundActions = new List<SoundAction>(10000);
  63. bool isRecording;
  64. float lastRecordedTime;
  65. public bool IsRecording
  66. {
  67. get
  68. {
  69. return isRecording;
  70. }
  71. set
  72. {
  73. isRecording = value;
  74. if (isRecording)
  75. {
  76. StartRecording();
  77. }
  78. else
  79. {
  80. StopRecording();
  81. }
  82. }
  83. }
  84. void StartRecording()
  85. {
  86. isRecording = true;
  87. lastRecordedTime = Time.time;
  88. soundActions.Clear();
  89. }
  90. void StopRecording()
  91. {
  92. isRecording = false;
  93. }
  94. void RecordSoundAction(SoundEvent soundEvent, SoundActionType actionType)
  95. {
  96. SoundAction action;
  97. action.soundEvent = soundEvent;
  98. action.actionType = actionType;
  99. action.delay = Time.time - lastRecordedTime;
  100. lastRecordedTime = Time.time;
  101. soundActions.Add(action);
  102. }
  103. int currentPlaybackSound;
  104. public void PlayBack()
  105. {
  106. isRecording = false;
  107. currentPlaybackSound = 0;
  108. PlaySounds();
  109. }
  110. void PlaySounds()
  111. {
  112. float delay = 0;
  113. foreach (SoundAction soundAction in soundActions)
  114. {
  115. delay += soundAction.delay;
  116. Invoke("PlayNextSound", delay);
  117. }
  118. }
  119. void PlayNextSound()
  120. {
  121. SoundAction soundAction = soundActions[currentPlaybackSound];
  122. ++currentPlaybackSound;
  123. switch (soundAction.actionType)
  124. {
  125. case SoundActionType.Play:
  126. Play(soundAction.soundEvent);
  127. break;
  128. case SoundActionType.Stop:
  129. Stop(soundAction.soundEvent);
  130. break;
  131. case SoundActionType.Loop:
  132. Loop(soundAction.soundEvent);
  133. break;
  134. case SoundActionType.StopLoop:
  135. StopLoop(soundAction.soundEvent);
  136. break;
  137. }
  138. }
  139. public void DumpToPrefs()
  140. {
  141. string s = soundActions.Count + "\n";
  142. foreach (SoundAction soundAction in soundActions)
  143. {
  144. s += soundAction.delay + " " + (int)soundAction.actionType + " " + (int)soundAction.soundEvent + "\n";
  145. }
  146. PlayerPrefs.SetString("audioRecording", s);
  147. PlayerPrefs.Save();
  148. }
  149. public void DumpFromPrefs()
  150. {
  151. Debug.Log(PlayerPrefs.GetString("audioRecording"));
  152. }
  153. public void LoadFromText()
  154. {
  155. TextAsset txt = Resources.Load("audioRecording", typeof(TextAsset)) as TextAsset;
  156. ByteReader reader = new ByteReader(txt);
  157. int numOfActions = int.Parse(reader.ReadLine());
  158. soundActions.Clear();
  159. for (int i = 0; i < numOfActions; i++)
  160. {
  161. string line = reader.ReadLine();
  162. string[] tokens = line.Split(' ');
  163. SoundAction action;
  164. action.delay = float.Parse(tokens[0]);
  165. action.actionType = (SoundActionType)int.Parse(tokens[1]);
  166. action.soundEvent = (SoundEvent)int.Parse(tokens[2]);
  167. soundActions.Add(action);
  168. }
  169. PlayBack();
  170. }
  171. #endregion
  172. public SoundConfig[] soundConfigs;
  173. float sfxVolume = 1;
  174. float musicVolume = GameConstants.MUSIC_VOLUME;
  175. AudioSource[] audioSources;
  176. public static AudioSource SourceCelebSperm;
  177. #region Static helpers
  178. public static void PlayRandom(SoundEvent[] sounds)
  179. {
  180. AVDebug.Assert(sounds.Length != 0, "The passed sounds should not be empty");
  181. SoundEvent sound = sounds[UnityEngine.Random.Range(0, sounds.Length)];
  182. Play(sound);
  183. }
  184. public static void PlayRandomPitch(SoundEvent sound, float maxNegativePitch, float maxPositivePitch)
  185. {
  186. float randomPitch = 1 + UnityEngine.Random.Range(maxNegativePitch, maxPositivePitch);
  187. PlayWithPitch(sound, randomPitch);
  188. }
  189. public static void PlayWithPitch(SoundEvent soundEvent, float pitch)
  190. {
  191. //Debug.Log("PlayWithPitch");
  192. _instance._PlayWithPitch(soundEvent, pitch);
  193. }
  194. public static void PlayWithPitch(SoundEvent soundEvent, float pitch, float delay)
  195. {
  196. //Debug.Log("PlayWithPitch");
  197. _instance._PlayWithPitch(soundEvent, pitch, delay);
  198. }
  199. public static void Play(SoundEvent soundEvent)
  200. {
  201. _instance._Play(soundEvent);
  202. }
  203. public static void Play(SoundEvent soundEvent, float delay)
  204. {
  205. _instance._Play(soundEvent, delay);
  206. }
  207. public static float ClipLength(SoundEvent soundEvent)
  208. {
  209. return _instance._ClipLength(soundEvent);
  210. }
  211. public static void Stop(SoundEvent soundEvent)
  212. {
  213. _instance._Stop(soundEvent);
  214. }
  215. public static void Loop(SoundEvent soundEvent)
  216. {
  217. _instance._Loop(soundEvent);
  218. }
  219. public static void StopLoop(SoundEvent soundEvent)
  220. {
  221. _instance._StopLoop(soundEvent);
  222. }
  223. #endregion
  224. void _Play(SoundEvent soundEvent)
  225. {
  226. if(musicVolume >0)
  227. {
  228. SoundConfig soundConfig = soundConfigs[(int)soundEvent];
  229. AudioSource audioSource = GetAudioSourceFor(soundEvent);
  230. SourceCelebSperm = audioSource;
  231. audioSource.pitch = soundConfig.pitch;
  232. audioSource.clip = soundConfig.clip;
  233. audioSource.Play();
  234. //Debug.Log(audioSource);
  235. if (isRecording)
  236. {
  237. RecordSoundAction(soundEvent, SoundActionType.Play);
  238. }
  239. }
  240. }
  241. void _Play(SoundEvent soundEvent, float delay)
  242. {
  243. StartCoroutine(DelayedPlayCoroutine(soundEvent, delay));
  244. }
  245. IEnumerator DelayedPlayCoroutine(SoundEvent soundEvent, float delay)
  246. {
  247. yield return new WaitForSeconds(delay);
  248. if (!MenuManager._instance.ExitToMainMenu)
  249. {
  250. _Play(soundEvent);
  251. }
  252. }
  253. void _PlayWithPitch(SoundEvent soundEvent, float pitch, float delay)
  254. {
  255. StartCoroutine(DelayedPlayWithPitchCoroutine(soundEvent, pitch, delay));
  256. }
  257. IEnumerator DelayedPlayWithPitchCoroutine(SoundEvent soundEvent, float pitch, float delay)
  258. {
  259. yield return new WaitForSeconds(delay);
  260. _PlayWithPitch(soundEvent, pitch);
  261. }
  262. void _PlayWithPitch(SoundEvent soundEvent, float pitch)
  263. {
  264. SoundConfig soundConfig = soundConfigs[(int)soundEvent];
  265. AudioSource audioSource = GetAudioSourceFor(soundEvent);
  266. audioSource.pitch = pitch;
  267. audioSource.PlayOneShot(soundConfig.clip, soundConfig.volume * sfxVolume);
  268. if (isRecording)
  269. {
  270. RecordSoundAction(soundEvent, SoundActionType.Play);
  271. }
  272. }
  273. public float _ClipLength(SoundEvent soundEvent)
  274. {
  275. SoundConfig soundConfig = soundConfigs[(int)soundEvent];
  276. return soundConfig.clip.length;
  277. }
  278. void _Stop(SoundEvent soundEvent)
  279. {
  280. audioSources[(int)soundEvent].Stop();
  281. if (isRecording)
  282. {
  283. RecordSoundAction(soundEvent, SoundActionType.Stop);
  284. }
  285. }
  286. void _Loop(SoundEvent soundEvent)
  287. {
  288. SoundConfig soundConfig = soundConfigs[(int)soundEvent];
  289. AudioSource audioSource = GetAudioSourceFor(soundEvent);
  290. audioSource.clip = soundConfig.clip;
  291. /*if (audioSource.clip.name == "loop_PointCounter")
  292. {
  293. MenuManager._instance.audioLoop = audioSource;
  294. }*/
  295. audioSource.loop = true;
  296. audioSource.volume = soundConfig.volume * sfxVolume;
  297. audioSource.pitch = soundConfig.pitch;
  298. audioSource.Play();
  299. if (isRecording)
  300. {
  301. RecordSoundAction(soundEvent, SoundActionType.Loop);
  302. }
  303. }
  304. void _StopLoop(SoundEvent soundEvent)
  305. {
  306. AudioSource audioSource = GetAudioSourceFor(soundEvent);
  307. audioSource.loop = false;
  308. audioSource.Stop();
  309. if (isRecording)
  310. {
  311. RecordSoundAction(soundEvent, SoundActionType.StopLoop);
  312. }
  313. }
  314. public AudioSource GetAudioSourceFor(SoundEvent soundEvent)
  315. {
  316. int i = (int)soundEvent;
  317. if (audioSources[i] == null)
  318. {
  319. audioSources[i] = gameObject.AddComponent<AudioSource>();
  320. }
  321. return audioSources[i];
  322. }
  323. public float SfxVolume
  324. {
  325. get
  326. {
  327. return sfxVolume;
  328. }
  329. set
  330. {
  331. SetSfxVolume(value);
  332. }
  333. }
  334. public float MusicVolume
  335. {
  336. get
  337. {
  338. return musicVolume;
  339. }
  340. set
  341. {
  342. SetMusicVolume(value);
  343. }
  344. }
  345. public void SetSfxVolume(float value)
  346. {
  347. sfxVolume = value;
  348. PlayerPrefs.SetFloat("sfxVolume", sfxVolume);
  349. PlayerPrefs.Save();
  350. //scale to new volume
  351. foreach (AudioSource s in audioSources)
  352. {
  353. if (s != null)
  354. {
  355. s.volume = sfxVolume;
  356. }
  357. }
  358. }
  359. public void SetMusicVolume(float value)
  360. {
  361. musicVolume = value;
  362. PlayerPrefs.SetFloat("musicVolume", musicVolume);
  363. PlayerPrefs.Save();
  364. MusicManager.Instance.SetMusicVolume(value);
  365. }
  366. }