116 lines
3.4 KiB
C#
116 lines
3.4 KiB
C#
|
|
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
|
|||
|
|
}
|