123 lines
No EOL
3.4 KiB
C#
Executable file
123 lines
No EOL
3.4 KiB
C#
Executable file
using UnityEngine.Audio;
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
public class MANAGER_Music : MonoBehaviour
|
|
{
|
|
public static MANAGER_Music Instance;
|
|
|
|
[Header("Main Settings")]
|
|
[Range(0f, 1f)]
|
|
[SerializeField] private float maxVolume = 0.5f;
|
|
[SerializeField] private float fadeDuration = 1.5f;
|
|
|
|
[Tooltip("Настрой кривую: 0,0 -> 1,1. Плавный выход в начале и конце сделает переход естественнее.")]
|
|
[SerializeField] private AnimationCurve fadeCurve = AnimationCurve.Linear(0, 0, 1, 1);
|
|
|
|
private AudioSource sourceA;
|
|
private AudioSource sourceB;
|
|
private AudioSource activeSource;
|
|
private Coroutine fadeCoroutine;
|
|
|
|
[Header("Mixer Settings")]
|
|
[SerializeField] private AudioMixerGroup musicGroup;
|
|
|
|
private Dictionary<AudioClip, float> savedPlaybackTimes = new Dictionary<AudioClip, float>();
|
|
|
|
void Awake()
|
|
{
|
|
if (Instance == null)
|
|
{
|
|
Instance = this;
|
|
SetupSources();
|
|
}
|
|
else
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
|
|
private void SetupSources()
|
|
{
|
|
sourceA = gameObject.AddComponent<AudioSource>();
|
|
sourceB = gameObject.AddComponent<AudioSource>();
|
|
|
|
if (musicGroup != null)
|
|
{
|
|
sourceA.outputAudioMixerGroup = musicGroup;
|
|
sourceB.outputAudioMixerGroup = musicGroup;
|
|
}
|
|
|
|
sourceA.loop = sourceB.loop = true;
|
|
sourceA.playOnAwake = sourceB.playOnAwake = false;
|
|
|
|
activeSource = sourceA;
|
|
activeSource.volume = 0;
|
|
}
|
|
|
|
public void SwitchMusic(AudioClip newClip)
|
|
{
|
|
if (activeSource.clip == newClip) return;
|
|
|
|
AudioSource nextSource = (activeSource == sourceA) ? sourceB : sourceA;
|
|
|
|
if (fadeCoroutine != null) StopCoroutine(fadeCoroutine);
|
|
fadeCoroutine = StartCoroutine(FadeSequence(nextSource, newClip));
|
|
}
|
|
|
|
private IEnumerator FadeSequence(AudioSource nextSource, AudioClip newClip)
|
|
{
|
|
float t = 0;
|
|
float startVol = activeSource.volume;
|
|
|
|
if (newClip != null)
|
|
{
|
|
nextSource.clip = newClip;
|
|
|
|
if (savedPlaybackTimes.TryGetValue(newClip, out float savedTime))
|
|
{
|
|
nextSource.time = savedTime;
|
|
}
|
|
else
|
|
{
|
|
nextSource.time = 0f;
|
|
}
|
|
|
|
nextSource.Play();
|
|
}
|
|
|
|
while (t < fadeDuration)
|
|
{
|
|
t += Time.deltaTime;
|
|
float progress = t / fadeDuration;
|
|
float curveValue = fadeCurve.Evaluate(progress);
|
|
|
|
activeSource.volume = Mathf.Lerp(startVol, 0, curveValue);
|
|
|
|
if (newClip != null)
|
|
nextSource.volume = Mathf.Lerp(0, maxVolume, curveValue);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
if (activeSource.clip != null)
|
|
{
|
|
savedPlaybackTimes[activeSource.clip] = activeSource.time;
|
|
}
|
|
|
|
activeSource.Stop();
|
|
activeSource.volume = 0;
|
|
|
|
activeSource = nextSource;
|
|
activeSource.volume = maxVolume;
|
|
fadeCoroutine = null;
|
|
}
|
|
|
|
public void SetVolume(float volume)
|
|
{
|
|
maxVolume = Mathf.Clamp01(volume);
|
|
if (activeSource != null) activeSource.volume = maxVolume;
|
|
}
|
|
} |