|
@ -0,0 +1,151 @@ |
|
|
|
|
|
using System.Collections; |
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
|
using UnityEngine; |
|
|
|
|
|
using NaughtyAttributes; |
|
|
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
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<AudioClip> m_playingClips = new List<AudioClip>(); |
|
|
|
|
|
#endregion Private Fields
|
|
|
|
|
|
|
|
|
|
|
|
#region Getters
|
|
|
|
|
|
|
|
|
|
|
|
#endregion Getters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region MonoBehaviour Functions
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// OnEnable is called when the object becomes enabled and active.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnEnable() |
|
|
|
|
|
{ |
|
|
|
|
|
instance = this; |
|
|
|
|
|
DontDestroyOnLoad(transform.root.gameObject); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// OnDisable is called when the behaviour becomes disabled.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void OnDisable() |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void OnDestroy() |
|
|
|
|
|
{ |
|
|
|
|
|
instance= null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Update is called once per frame
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
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<SFXPlayer>(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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<AudioSource>(); |
|
|
|
|
|
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
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Called when the Component is created or Reset from the Inspector
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void Reset() |
|
|
|
|
|
{ |
|
|
|
|
|
//useful for finding components on creation
|
|
|
|
|
|
} |
|
|
|
|
|
#endregion Editor Functions
|
|
|
|
|
|
|
|
|
|
|
|
} |