87 lines
2.5 KiB
C#
87 lines
2.5 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using System.Threading;
|
|
using UnityEngine;
|
|
using UnityEngine.Audio;
|
|
|
|
public class MixerController : MonoBehaviour
|
|
{
|
|
const string LowpassCutoffFreq = "LowpassCutoffFreq";
|
|
const string LowpassResonance = "LowpassResonance";
|
|
|
|
[SerializeField] AudioMixer mixer;
|
|
|
|
[Header("Фильтры над водой")]
|
|
[SerializeField] float upCutoff = 22000f;
|
|
[SerializeField] float upResonance = 1f;
|
|
[SerializeField] float upSpeed = 0.5f;
|
|
|
|
[Header("Фильтры под водой")]
|
|
[SerializeField] float downCutoff = 1000f;
|
|
[SerializeField] float downResonance = 2f;
|
|
[SerializeField] float downSpeed = 1.5f;
|
|
|
|
private CancellationTokenSource cts;
|
|
private bool initialized = false;
|
|
private float t = 1;
|
|
|
|
public void Init()
|
|
{
|
|
G.PlayerStateModel.PlayerComponent.DiveSystem.Dived += DiveSystem_Dived;
|
|
G.PlayerStateModel.PlayerComponent.DiveSystem.Surfaced += DiveSystem_Surfaced;
|
|
|
|
mixer.SetFloat(LowpassCutoffFreq, upCutoff);
|
|
mixer.SetFloat(LowpassResonance, upResonance);
|
|
|
|
initialized = true;
|
|
}
|
|
|
|
private void DiveSystem_Surfaced() => SetUnderwater(goingDown: false);
|
|
private void DiveSystem_Dived() => SetUnderwater(goingDown: true);
|
|
|
|
public void SetUnderwater(bool goingDown)
|
|
{
|
|
|
|
cts?.Cancel();
|
|
cts?.Dispose();
|
|
cts = new();
|
|
|
|
var speed = goingDown ? downSpeed : upSpeed;
|
|
SetFiltersAsync(goingDown, speed, cts.Token).Forget();
|
|
}
|
|
|
|
private async UniTask SetFiltersAsync(bool goingDown, float speed, CancellationToken token)
|
|
{
|
|
float targetT = goingDown ? 0 : 1;
|
|
while(t != targetT && !token.IsCancellationRequested)
|
|
{
|
|
float delta = Time.deltaTime * speed;
|
|
t = Mathf.MoveTowards(t, targetT, delta);
|
|
|
|
var cutoff = Mathf.Lerp(downCutoff, upCutoff, t);
|
|
var resonance = Mathf.Lerp(downResonance, upResonance, t);
|
|
|
|
mixer.SetFloat(LowpassCutoffFreq, cutoff);
|
|
mixer.SetFloat(LowpassResonance, resonance);
|
|
|
|
await UniTask.Yield(PlayerLoopTiming.Update, token);
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
cts?.Cancel();
|
|
cts?.Dispose();
|
|
|
|
mixer.SetFloat(LowpassCutoffFreq, upCutoff);
|
|
mixer.SetFloat(LowpassResonance, upResonance);
|
|
|
|
if(initialized)
|
|
{
|
|
G.PlayerStateModel.PlayerComponent.DiveSystem.Dived -= DiveSystem_Dived;
|
|
G.PlayerStateModel.PlayerComponent.DiveSystem.Surfaced -= DiveSystem_Surfaced;
|
|
}
|
|
}
|
|
|
|
|
|
}
|