PJ/Assets/scripts/dotfs_scripts/GlobalMusicManager.cs

116 lines
3.4 KiB
C#
Raw Normal View History

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<AudioSource>();
// Если SFX источник не назначен, создадим его или найдем второй
if (_sfxSource == null)
{
_sfxSource = gameObject.AddComponent<AudioSource>();
}
_musicSource.ignoreListenerPause = true;
}
else
{
Destroy(gameObject);
}
}
#region Volume Control
/// <summary>
/// Универсальный метод для установки громкости музыки (для Слайдера 0...1)
/// </summary>
public void SetMusicVolume(float volume)
{
SetMixerVolume(_musicParameter, volume);
}
/// <summary>
/// Универсальный метод для установки громкости SFX (для Слайдера 0...1)
/// </summary>
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
/// <summary>
/// Проигрывает звуковой эффект один раз
/// </summary>
public void PlaySFX(AudioClip clip, float pitch = 1f)
{
if (clip == null || _sfxSource == null) return;
_sfxSource.pitch = pitch;
_sfxSource.PlayOneShot(clip);
}
#endregion
}