160 lines
No EOL
5.8 KiB
C#
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;
|
|
}
|
|
} |