sea-battle-vr/Assets/Scripts/MixerController.cs

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;
}
}
}