PJ/Assets/scripts/dotfs_scripts/SFX_AudioControl.cs

160 lines
No EOL
5.8 KiB
C#

using UnityEngine;
using UnityEngine.Audio;
using System.Collections;
public class SFX_AudioControl : MonoBehaviour
{
public static SFX_AudioControl Instance; // Синглтон для быстрого доступа
[Header("Snapshots для спецэффектов")]
public AudioMixerSnapshot defaultSnapshot; // Обычное состояние
public AudioMixerSnapshot dimmedSnapshot; // Музыка приглушена
[Header("Настройки микшера")]
public AudioMixer mixer;
public string mainMusicParam = "Main";
public string mysteryMusicParam = "Mystery";
[Header("Звуковые источники (SFX)")]
public AudioSource sfxSource; // Источник для звуков интерфейса
public AudioClip transitionSFX;
public AudioClip defaultPurchaseSFX; // Звук покупки по умолчанию
public AudioClip defaultErrorSFX; // Звук ошибки по умолчанию
[Header("Мистический трек")]
public AudioMixerGroup mysteryGroup;
public AudioClip mysteryClip;
private AudioSource mysterySource;
[Header("Затемнение экрана")]
public CanvasGroup darkOverlayGroup;
public float darkAlpha = 0.8f;
public float darkFadeInSpeed = 1.0f;
public float darkFadeOutSpeed = 1.5f;
[Header("Настройки громкости")]
public float mainMaxVol = -1f;
public float mysteryMaxVol = 0f;
public float dimmedVol = -80f;
private bool isMystery = false;
private void Awake()
{
// Инициализация синглтона
if (Instance == null) Instance = this;
mysterySource = gameObject.AddComponent<AudioSource>();
mysterySource.clip = mysteryClip;
mysterySource.loop = true;
mysterySource.playOnAwake = false;
mysterySource.outputAudioMixerGroup = mysteryGroup;
if (darkOverlayGroup != null) darkOverlayGroup.alpha = 0f;
}
private void Start()
{
mixer.SetFloat(mainMusicParam, mainMaxVol);
mixer.SetFloat(mysteryMusicParam, dimmedVol);
if (mysteryClip != null) mysterySource.Play();
}
// Универсальный метод для проигрывания звука
public void PlayOneShot(AudioClip clip)
{
if (clip != null && sfxSource != null)
{
sfxSource.PlayOneShot(clip);
}
}
public void PlaySfxWithDucking(AudioClip clip)
{
if (clip == null) return;
StartCoroutine(DuckingRoutine(clip));
}
private IEnumerator DuckingRoutine(AudioClip clip)
{
// Переключаемся на "тихий" снимок (музыка плавно гаснет)
if (dimmedSnapshot != null)
dimmedSnapshot.TransitionTo(0.2f);
sfxSource.PlayOneShot(clip);
// Ждем, пока звук доиграет (или чуть меньше/больше)
yield return new WaitForSeconds(clip.length);
// Возвращаем музыку в норму
if (defaultSnapshot != null)
defaultSnapshot.TransitionTo(0.5f);
}
// Почва для JSON: метод, который принимает ID (строку)
// Сейчас он просто логирует, но здесь ты добавишь поиск в словаре/базе данных
public void PlaySfxById(string sfxId, AudioClip fallbackClip)
{
// Если ID пустой, играем дефолтный клип из инспектора
if (string.IsNullOrEmpty(sfxId))
{
PlayOneShot(fallbackClip);
return;
}
// Логика поиска клипа по ID из JSON (например, через Dictionary или Resources)
// AudioClip clipFromDb = YourAudioDatabase.GetClip(sfxId);
// PlayOneShot(clipFromDb);
Debug.Log($"[SFX] Пытаемся проиграть звук по ID из JSON: {sfxId}. Пока играем fallback.");
PlayOneShot(fallbackClip);
}
// --- Твои старые методы переходов ---
public void SwitchToMystery(float audioDuration)
{
if (isMystery) return;
isMystery = true;
StopAllCoroutines();
PlayOneShot(transitionSFX);
StartCoroutine(FadeMixer(mainMusicParam, dimmedVol, audioDuration));
StartCoroutine(FadeMixer(mysteryMusicParam, mysteryMaxVol, audioDuration));
if (darkOverlayGroup != null) StartCoroutine(FadeDarkness(darkAlpha, darkFadeInSpeed));
}
public void ReturnToMain(float audioDuration)
{
if (!isMystery) return;
isMystery = false;
StopAllCoroutines();
StartCoroutine(FadeMixer(mainMusicParam, mainMaxVol, audioDuration));
StartCoroutine(FadeMixer(mysteryMusicParam, dimmedVol, audioDuration));
if (darkOverlayGroup != null) StartCoroutine(FadeDarkness(0f, darkFadeOutSpeed));
}
private IEnumerator FadeMixer(string paramName, float targetValue, float duration)
{
mixer.GetFloat(paramName, out float startValue);
float time = 0;
while (time < duration)
{
time += Time.unscaledDeltaTime;
mixer.SetFloat(paramName, Mathf.Lerp(startValue, targetValue, time / duration));
yield return null;
}
mixer.SetFloat(paramName, targetValue);
}
private IEnumerator FadeDarkness(float targetAlpha, float duration)
{
float startAlpha = darkOverlayGroup.alpha;
float time = 0;
while (time < duration)
{
time += Time.unscaledDeltaTime;
darkOverlayGroup.alpha = Mathf.Lerp(startAlpha, targetAlpha, time / duration);
yield return null;
}
darkOverlayGroup.alpha = targetAlpha;
}
}