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(); 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; } }