using UnityEngine; using UnityEngine.Audio; // Обязательно для работы с микшером [RequireComponent(typeof(AudioSource))] public class GlobalMusicManager : MonoBehaviour { public static GlobalMusicManager Instance { get; private set; } [Header("Audio Sources")] [SerializeField] private AudioSource _musicSource; [SerializeField] private AudioSource _sfxSource; // Отдельный источник для эффектов [Header("Mixer Settings")] [SerializeField] private AudioMixer _audioMixer; [SerializeField] private string _musicParameter = "MusicVolume"; // Имя параметра в микшере [SerializeField] private string _sfxParameter = "SFXVolume"; // Имя параметра в микшере private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); if (_musicSource == null) _musicSource = GetComponent(); // Если SFX источник не назначен, создадим его или найдем второй if (_sfxSource == null) { _sfxSource = gameObject.AddComponent(); } _musicSource.ignoreListenerPause = true; } else { Destroy(gameObject); } } #region Volume Control /// /// Универсальный метод для установки громкости музыки (для Слайдера 0...1) /// public void SetMusicVolume(float volume) { SetMixerVolume(_musicParameter, volume); } /// /// Универсальный метод для установки громкости SFX (для Слайдера 0...1) /// public void SetSFXVolume(float volume) { SetMixerVolume(_sfxParameter, volume); } private void SetMixerVolume(string parameterName, float sliderValue) { // Ограничиваем значение, чтобы Log10 не выдал ошибку при 0 float volume = Mathf.Clamp(sliderValue, 0.0001f, 1f); // Формула перевода линейного значения 0..1 в децибелы -80..0 _audioMixer.SetFloat(parameterName, Mathf.Log10(volume) * 20); } #endregion #region Music Logic public void PlayMusic(AudioClip clip) { if (_musicSource == null) return; if (clip == null) { StopMusic(); return; } if (_musicSource.clip == clip) { if (!_musicSource.isPlaying) _musicSource.Play(); return; } _musicSource.clip = clip; _musicSource.loop = true; _musicSource.Play(); } public void StopMusic() { if (_musicSource != null) { _musicSource.Stop(); _musicSource.clip = null; } } #endregion #region SFX Logic /// /// Проигрывает звуковой эффект один раз /// public void PlaySFX(AudioClip clip, float pitch = 1f) { if (clip == null || _sfxSource == null) return; _sfxSource.pitch = pitch; _sfxSource.PlayOneShot(clip); } #endregion }