using System.Collections; using System.Collections.Generic; using UnityEngine; using NaughtyAttributes; using System.Linq; /// /// /// public class SFXPlayer : MonoBehaviour { private static SFXPlayer instance; #region Inspector Fields [SerializeField, MinMaxSlider(-1, 1)] public Vector2 pitchRange = new Vector2(-0.1f, 0.1f); [SerializeField, MinMaxSlider(-1, 1)] public Vector2 volumeRange = new Vector2(-0.1f, 0.1f); #endregion Inspector Fields #region Private Fields private List m_playingClips = new List(); #endregion Private Fields #region Getters #endregion Getters #region MonoBehaviour Functions /// /// OnEnable is called when the object becomes enabled and active. /// private void OnEnable() { instance = this; DontDestroyOnLoad(transform.root.gameObject); } /// /// OnDisable is called when the behaviour becomes disabled. /// private void OnDisable() { } private void OnDestroy() { instance= null; } /// /// Update is called once per frame /// private void Update() { } #endregion MonoBehaviour Functions #region Class Functionality public static void Play(params AudioClip[] clip) { CreateInstace(); instance?.PlaySoundClip(clip); } public static bool isPlaying(params AudioClip[] clips) { if (instance == null) return false; foreach (AudioClip clip in clips) if (instance.m_playingClips.Contains(clip)) return true; return false; } private static void CreateInstace() { if (instance != null) return; GameObject gameObject = new GameObject("SFX Player"); gameObject.AddComponent(); } public void PlaySoundClip(params AudioClip[] clips) { if (clips.Length == 0 || isPlaying(clips)) return; AudioClip selectedClip = clips[Random.Range(0, clips.Length)]; GameObject gameObject = new GameObject(selectedClip.name); gameObject.transform.parent = transform; AudioSource source = gameObject.AddComponent(); source.clip = selectedClip; source.volume = 0.8f + Random.Range(volumeRange.x, volumeRange.y); source.pitch = 1 + Random.Range(pitchRange.y, pitchRange.x); source.spatialBlend = 0; m_playingClips.AddRange(clips); source.Play(); StartCoroutine(DestroyAfter(selectedClip.length,gameObject , clips)); } private IEnumerator DestroyAfter(float t,GameObject gameObject, params AudioClip[] clips) { yield return new WaitForSeconds(t); m_playingClips.RemoveAll(p => clips.Contains(p)); Destroy(gameObject); } #endregion Class Functionality #region Editor Functions /// /// Called when the Component is created or Reset from the Inspector /// private void Reset() { //useful for finding components on creation } #endregion Editor Functions }