66 lines
2.2 KiB
C#
66 lines
2.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Management
|
|
{
|
|
/// <summary>
|
|
/// Single drive to play all SFX in game. Contains a limiter that limits amount of times
|
|
/// any one clip will play to prevent volume runaways and other sound wave based oddities.
|
|
/// </summary>
|
|
[RequireComponent(typeof(AudioSource))]
|
|
public class SFX : MonoBehaviour
|
|
{
|
|
// The maximum number any individual clip can be played.
|
|
[SerializeField] private int maxActiveClips;
|
|
|
|
// singleton pattern
|
|
private static SFX _instance;
|
|
|
|
// audio driver
|
|
private AudioSource _audioSource;
|
|
|
|
// Playing clip registry. Used as data source to limit amount of times a clip will play simultaneously
|
|
private Dictionary<AudioClip, int> _clipsInProgress;
|
|
|
|
/// <summary>
|
|
/// Plpays the given audio clip through the audio driver
|
|
/// </summary>
|
|
/// <param name="clip">The sound to play</param>
|
|
/// <param name="volume">The normalized volume it will play at</param>
|
|
public void PlayOneShot(AudioClip clip, float volume = 1f)
|
|
{
|
|
if (clip == null) return;
|
|
if (!_clipsInProgress.TryAdd(clip, 1))
|
|
{
|
|
if (_clipsInProgress[clip] >= maxActiveClips) return;
|
|
_clipsInProgress[clip]++;
|
|
}
|
|
|
|
_audioSource.PlayOneShot(clip, volume);
|
|
StartCoroutine(ClearClip(clip));
|
|
}
|
|
|
|
// Coroutine to clear registry once sound is finished.
|
|
private IEnumerator ClearClip(AudioClip clip)
|
|
{
|
|
yield return new WaitForSeconds(clip.length);
|
|
_clipsInProgress[clip]--;
|
|
if (_clipsInProgress[clip] <= 0) _clipsInProgress.Remove(clip);
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (_instance != null && _instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
|
|
_instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
_audioSource = GetComponent<AudioSource>();
|
|
}
|
|
}
|
|
}
|