Global Game Jam 2023
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
3.2 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using NaughtyAttributes;
  5. using System.Linq;
  6. /// <summary>
  7. ///
  8. /// </summary>
  9. public class SFXPlayer : MonoBehaviour
  10. {
  11. private static SFXPlayer instance;
  12. #region Inspector Fields
  13. [SerializeField, MinMaxSlider(-1, 1)]
  14. public Vector2 pitchRange = new Vector2(-0.1f, 0.1f);
  15. [SerializeField, MinMaxSlider(-1, 1)]
  16. public Vector2 volumeRange = new Vector2(-0.1f, 0.1f);
  17. #endregion Inspector Fields
  18. #region Private Fields
  19. private List<AudioClip> m_playingClips = new List<AudioClip>();
  20. #endregion Private Fields
  21. #region Getters
  22. #endregion Getters
  23. #region MonoBehaviour Functions
  24. /// <summary>
  25. /// OnEnable is called when the object becomes enabled and active.
  26. /// </summary>
  27. private void OnEnable()
  28. {
  29. instance = this;
  30. DontDestroyOnLoad(transform.root.gameObject);
  31. }
  32. /// <summary>
  33. /// OnDisable is called when the behaviour becomes disabled.
  34. /// </summary>
  35. private void OnDisable()
  36. {
  37. }
  38. private void OnDestroy()
  39. {
  40. instance= null;
  41. }
  42. /// <summary>
  43. /// Update is called once per frame
  44. /// </summary>
  45. private void Update()
  46. {
  47. }
  48. #endregion MonoBehaviour Functions
  49. #region Class Functionality
  50. public static void Play(params AudioClip[] clip)
  51. {
  52. CreateInstace();
  53. instance?.PlaySoundClip(clip);
  54. }
  55. public static bool isPlaying(params AudioClip[] clips)
  56. {
  57. if (instance == null)
  58. return false;
  59. foreach (AudioClip clip in clips)
  60. if (instance.m_playingClips.Contains(clip))
  61. return true;
  62. return false;
  63. }
  64. private static void CreateInstace()
  65. {
  66. if (instance != null)
  67. return;
  68. GameObject gameObject = new GameObject("SFX Player");
  69. gameObject.AddComponent<SFXPlayer>();
  70. }
  71. public void PlaySoundClip(params AudioClip[] clips)
  72. {
  73. if (clips.Length == 0 || isPlaying(clips))
  74. return;
  75. AudioClip selectedClip = clips[Random.Range(0, clips.Length)];
  76. GameObject gameObject = new GameObject(selectedClip.name);
  77. gameObject.transform.parent = transform;
  78. AudioSource source = gameObject.AddComponent<AudioSource>();
  79. source.clip = selectedClip;
  80. source.volume = 0.8f + Random.Range(volumeRange.x, volumeRange.y);
  81. source.pitch = 1 + Random.Range(pitchRange.y, pitchRange.x);
  82. source.spatialBlend = 0;
  83. m_playingClips.AddRange(clips);
  84. source.Play();
  85. StartCoroutine(DestroyAfter(selectedClip.length,gameObject , clips));
  86. }
  87. private IEnumerator DestroyAfter(float t,GameObject gameObject, params AudioClip[] clips)
  88. {
  89. yield return new WaitForSeconds(t);
  90. m_playingClips.RemoveAll(p => clips.Contains(p));
  91. Destroy(gameObject);
  92. }
  93. #endregion Class Functionality
  94. #region Editor Functions
  95. /// <summary>
  96. /// Called when the Component is created or Reset from the Inspector
  97. /// </summary>
  98. private void Reset()
  99. {
  100. //useful for finding components on creation
  101. }
  102. #endregion Editor Functions
  103. }