137 lines
3.7 KiB
C#
137 lines
3.7 KiB
C#
using System.Collections;
|
||
using DG.Tweening;
|
||
using UnityEngine;
|
||
|
||
public class SoundManager : MonoBehaviour
|
||
{
|
||
public static SoundManager instance;
|
||
|
||
[SerializeField] private AudioSource _musicSource;
|
||
[SerializeField] private AudioSource _sfxSource;
|
||
[SerializeField] private AudioClip _columnSelectionClip;
|
||
|
||
private Tween _musicFadeTween;
|
||
private Coroutine _musicDuckCoroutine;
|
||
|
||
public float MusicVolume { get; private set; } = 0.5f;
|
||
|
||
private void OnDestroy()
|
||
{
|
||
if (instance != this)
|
||
return;
|
||
|
||
SettingsManager.OnSettingsChanged -= ApplySettings;
|
||
_musicFadeTween?.Kill();
|
||
instance = null;
|
||
}
|
||
|
||
public void Initialize()
|
||
{
|
||
if (instance != null && instance != this)
|
||
{
|
||
Destroy(gameObject);
|
||
return;
|
||
}
|
||
|
||
instance = this;
|
||
ApplySettings();
|
||
SettingsManager.OnSettingsChanged -= ApplySettings;
|
||
SettingsManager.OnSettingsChanged += ApplySettings;
|
||
|
||
if (_musicSource.clip != null && _musicSource.isPlaying == false)
|
||
_musicSource.Play();
|
||
}
|
||
|
||
public void ApplySettings()
|
||
{
|
||
MusicVolume = SettingsManager.GetFloat(SettingKey.MUSIC_VOLUME);
|
||
_musicSource.volume = MusicVolume;
|
||
_sfxSource.volume = SettingsManager.GetFloat(SettingKey.SOUNDS_VOLUME);
|
||
}
|
||
|
||
public void PlaySfx(AudioClip clip)
|
||
=> PlaySfx(clip, 1f);
|
||
|
||
public void PlaySfx(AudioClip clip, float relativeVolume)
|
||
{
|
||
if (clip == null)
|
||
{
|
||
Debug.LogWarning("Не установлен звук");
|
||
return;
|
||
}
|
||
|
||
_sfxSource.PlayOneShot(clip, Mathf.Max(0f, relativeVolume));
|
||
}
|
||
|
||
public void PlayColumnSelectionSound()
|
||
{
|
||
if (_columnSelectionClip != null)
|
||
PlaySfx(_columnSelectionClip);
|
||
}
|
||
|
||
public void FadeMusic(bool enable, float duration)
|
||
{
|
||
StopMusicTransitions();
|
||
float targetVolume = enable ? MusicVolume : 0f;
|
||
_musicFadeTween = _musicSource.DOFade(targetVolume, duration);
|
||
_musicFadeTween.PlayForward();
|
||
}
|
||
|
||
public void DuckMusic(float fadeDuration, float holdDuration, float targetVolumePercent)
|
||
{
|
||
StopMusicTransitions();
|
||
_musicDuckCoroutine = StartCoroutine(
|
||
DuckMusicCoroutine(fadeDuration, holdDuration, targetVolumePercent));
|
||
}
|
||
|
||
private void StopMusicTransitions()
|
||
{
|
||
_musicFadeTween?.Kill();
|
||
_musicFadeTween = null;
|
||
|
||
if (_musicDuckCoroutine == null)
|
||
return;
|
||
|
||
StopCoroutine(_musicDuckCoroutine);
|
||
_musicDuckCoroutine = null;
|
||
}
|
||
|
||
private IEnumerator DuckMusicCoroutine(
|
||
float fadeDuration,
|
||
float holdDuration,
|
||
float targetVolumePercent)
|
||
{
|
||
float startVolume = MusicVolume;
|
||
float targetVolume = startVolume * Mathf.Clamp01(targetVolumePercent);
|
||
|
||
yield return FadeMusicVolume(startVolume, targetVolume, fadeDuration);
|
||
|
||
if (holdDuration > 0f)
|
||
yield return new WaitForSeconds(holdDuration);
|
||
|
||
yield return FadeMusicVolume(targetVolume, MusicVolume, fadeDuration);
|
||
_musicDuckCoroutine = null;
|
||
}
|
||
|
||
private IEnumerator FadeMusicVolume(float startVolume, float targetVolume, float duration)
|
||
{
|
||
if (duration <= 0f)
|
||
{
|
||
_musicSource.volume = targetVolume;
|
||
yield break;
|
||
}
|
||
|
||
float elapsedTime = 0f;
|
||
|
||
while (elapsedTime < duration)
|
||
{
|
||
elapsedTime += Time.deltaTime;
|
||
float progress = Mathf.Clamp01(elapsedTime / duration);
|
||
_musicSource.volume = Mathf.Lerp(startVolume, targetVolume, progress);
|
||
yield return null;
|
||
}
|
||
|
||
_musicSource.volume = targetVolume;
|
||
}
|
||
}
|