using Cysharp.Threading.Tasks; using System; using System.Threading; using UnityEngine; public class MenuAnimation : MonoBehaviour { [Header("Группы")] [SerializeField] private CanvasGroup beforePaymentGroup; [SerializeField] private CanvasGroup afterPaymentGroup; [SerializeField] private float switchSpeed = 4; [SerializeField] private float stayDelay = 2; [Header("Инструкция")] [SerializeField] private CanvasGroup startInstruction; [Header("Инструкция перископ")] [SerializeField] private CanvasGroup periscopeInstruction; [SerializeField] private Transform periscopeTransform; [SerializeField] private float upPosition = 100; [SerializeField] private float downPosition = -50; [SerializeField] private AnimationCurve curve; [SerializeField] private CanvasGroup upGroup; [SerializeField] private CanvasGroup downGroup; [Header("Градиент")] [SerializeField] private CanvasGroup gradient; [SerializeField] private float gradientTransitionSpeed = 2; private CancellationTokenSource cts; private bool payed = false; public void Init(bool alreadyPayed) { beforePaymentGroup.alpha = alreadyPayed ? 0f : 1f; afterPaymentGroup.alpha = alreadyPayed ? 1 : 0f; gradient.alpha = alreadyPayed ? 1f : 0f; startInstruction.alpha = 0; periscopeInstruction.alpha = 1; upGroup.alpha = 0; downGroup.alpha = 0; if (alreadyPayed) { payed = true; StartInstructionAnimation(); } } private void Update() { if (Input.GetKeyDown(KeyCode.R)) { WalletManager.ResetBalance(); } } private void OnDestroy() => StopAnimation(); 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) { 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) { LerpAlpha(0, 1, gradientTransitionSpeed, gradient, ct).Forget(); await LerpAlpha(1, 0, switchSpeed, beforePaymentGroup, ct); await LerpAlpha(0, 1, switchSpeed, afterPaymentGroup, ct); } private async UniTask InstructionAnimation(CancellationToken ct) { while (!ct.IsCancellationRequested) { await InstructionPeriscope(ct); await UniTask.Delay(TimeSpan.FromSeconds(stayDelay / 4), cancellationToken: ct); await InstructionStart(ct); await UniTask.Delay(TimeSpan.FromSeconds(stayDelay / 4), cancellationToken: ct); } } private async UniTask InstructionPeriscope(CancellationToken ct) { downGroup.alpha = 0; upGroup.alpha = 1; LerpAlpha(0, 1, switchSpeed, periscopeInstruction, ct).Forget(); await MoveLocalY(upPosition, switchSpeed/2, periscopeTransform, curve, ct); await UniTask.Delay(TimeSpan.FromSeconds(stayDelay/2), cancellationToken: ct); await LerpAlpha(1, 0, switchSpeed*2, upGroup, ct); LerpAlpha(0, 1, switchSpeed*2, downGroup, ct).Forget(); await MoveLocalY(0, switchSpeed/2, periscopeTransform, curve, ct); LerpAlpha(1, 0, switchSpeed, periscopeInstruction, ct).Forget(); await UniTask.Delay(TimeSpan.FromSeconds(stayDelay/2), cancellationToken: ct); } private async UniTask InstructionStart(CancellationToken ct) { await LerpAlpha(0, 1, switchSpeed, startInstruction, ct); await UniTask.Delay(TimeSpan.FromSeconds(stayDelay), cancellationToken: ct); await LerpAlpha(1, 0, switchSpeed, startInstruction, ct); } private async UniTask LerpAlpha(float from, float to, float speed, CanvasGroup cg, CancellationToken ct) { float t = 0; while (t < 1 && !ct.IsCancellationRequested) { t += Time.deltaTime * speed; t = Mathf.Min(t, 1); cg.alpha = Mathf.Lerp(from, to, t); await UniTask.Yield(ct); } cg.alpha = to; } private async UniTask MoveLocalY(float targetY, float speed, Transform transform, AnimationCurve curve, CancellationToken ct) { float t = 0; float startY = transform.localPosition.y; while (!ct.IsCancellationRequested && t < 1) { t += Time.deltaTime * speed; t = Mathf.Min(t, 1); float t1 = curve.Evaluate(t); transform.localPosition = new Vector2(transform.localPosition.x, Mathf.Lerp(startY, targetY, t1)); await UniTask.Yield(ct); } transform.localPosition = new Vector2(transform.localPosition.x, targetY); } }