sea-battle-vr/Assets/Scripts/Menu/MenuAnimation.cs
2026-06-11 11:19:22 +03:00

174 lines
4.5 KiB
C#

using Cysharp.Threading.Tasks;
using System;
using System.Threading;
using Unity.Mathematics.Geometry;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MenuAnimation : MonoBehaviour
{
[Header("Группы")]
[SerializeField] private CanvasGroup beforePaymentGroup;
[SerializeField] private CanvasGroup afterPaymentGroup;
[Header("Инструкция")]
[SerializeField] private CanvasGroup startInstruction;
[SerializeField] private CanvasGroup periscopeInstruction;
[SerializeField] private float switchSpeed = 4;
[SerializeField] private float stayDelay = 2;
[Header("Градиент")]
[SerializeField] private RectTransform gradient;
[SerializeField] private float normalHeight = 440;
[SerializeField] private float payedHeight = 1080;
[SerializeField] private float gradientTransitionSpeed = 2;
private CancellationTokenSource cts;
bool payed = false;
public void Init(bool alreadyPayed)
{
beforePaymentGroup.alpha = alreadyPayed ? 0f : 1f;
afterPaymentGroup.alpha = alreadyPayed ? 1 : 0f;
float gradientHeight = alreadyPayed ? payedHeight : normalHeight;
gradient.sizeDelta = new Vector2(gradient.sizeDelta.x, gradientHeight);
startInstruction.alpha = 0;
periscopeInstruction.alpha = 1;
if (alreadyPayed)
{
payed = true;
StartInstructionAnimation();
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
WalletManager.ResetBalance();
}
}
private void OnDestroy()
{
cts?.Cancel();
cts?.Dispose();
}
private void StopAnimation()
{
cts?.Cancel();
cts?.Dispose();
cts = null;
}
public void PerformTransition()
{
if(payed) return;
StopAnimation();
cts = new CancellationTokenSource();
Transition(cts.Token).Forget();
}
private async UniTask Transition(CancellationToken ct)
{
GradientUp(ct).Forget();
await TransitionToInstruction(ct);
if (!ct.IsCancellationRequested)
{
await InstructionAnimation(ct);
}
}
public void StartInstructionAnimation()
{
StopAnimation();
cts = new CancellationTokenSource();
InstructionAnimation(cts.Token).Forget();
}
private async UniTask TransitionToInstruction(CancellationToken ct)
{
float t;
//тушим
t = 0;
while (t < 1 && !ct.IsCancellationRequested)
{
t += Time.deltaTime * switchSpeed;
t = Mathf.Min(t, 1);
beforePaymentGroup.alpha = 1 - t;
await UniTask.Yield(ct);
}
//Зажигаем
t = 0;
while (t < 1 && !ct.IsCancellationRequested)
{
t += Time.deltaTime * switchSpeed;
t = Mathf.Min(t, 1);
afterPaymentGroup.alpha = t;
await UniTask.Yield(ct);
}
}
private async UniTask GradientUp(CancellationToken ct)
{
float t = 0;
while(t < 1 && !ct.IsCancellationRequested)
{
t += Time.deltaTime * gradientTransitionSpeed;
t = Mathf.Min(t, 1);
float height = Mathf.Lerp(normalHeight, payedHeight, t);
gradient.sizeDelta = new Vector2(gradient.sizeDelta.x, height);
await UniTask.Yield(ct);
}
gradient.sizeDelta = new Vector2(gradient.sizeDelta.x, payedHeight);
}
private async UniTask InstructionAnimation(CancellationToken ct)
{
var ascendingGroup = startInstruction;
var descendingGroup = periscopeInstruction;
float t;
while (!ct.IsCancellationRequested)
{
await UniTask.Delay(TimeSpan.FromSeconds(stayDelay), cancellationToken: ct);
//тушим
t = 0;
while (t < 1 && !ct.IsCancellationRequested)
{
t += Time.deltaTime * switchSpeed;
t = Mathf.Min(t, 1);
descendingGroup.alpha = 1 - t;
await UniTask.Yield(ct);
}
//Зажигаем
t = 0;
while (t < 1 && !ct.IsCancellationRequested)
{
t += Time.deltaTime * switchSpeed;
t = Mathf.Min(t, 1);
ascendingGroup.alpha = t;
await UniTask.Yield(ct);
}
(ascendingGroup, descendingGroup) = (descendingGroup, ascendingGroup);
}
}
}