sea-battle-vr/Assets/Scripts/Awards/AwardsController.cs

171 lines
4.9 KiB
C#

using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Threading;
using TMPro;
using UnityEngine;
public class AwardsController : MonoBehaviour
{
[Header("Boot")]
[SerializeField] private Canvas canvas;
[SerializeField] private float timeout = 100;
[SerializeField] private string menuSceneName = "MenuOneRegime";
[SerializeField] private string gameplaySceneName = "Gameplay";
[Header("Анимация счетчиков")]
[SerializeField] private List<AwardsShipCounter> shipCounters;
[Header("Анимация счета")]
[SerializeField] private TextMeshProUGUI scoreLabel;
[SerializeField] private float scorePerSecond = 200;
[SerializeField] private float maxDuration = 3;
[Header("Анимация ранга")]
[SerializeField] private GameObject rankAnimation;
[SerializeField] private float rankAnimationTime = 4f;
[Header("Инструкция")]
[SerializeField] private float targetY = -20f;
[SerializeField] private AnimationCurve animationCurve;
[SerializeField] private float animationMoveDuration = 1;
[SerializeField] private RectTransform instructionPanel;
[SerializeField] private AwardsInstruction instruction;
[Header("Таймер")]
[SerializeField] private TextMeshProUGUI TimerLabel;
[SerializeField] private GameObject TimerGO;
private bool polling = false;
async void Start()
{
if (!BootstrapperState.MainBootstraped)
{
SceneLoader.LoadScene("Bootstrap");
return;
}
Setup();
Debug.Log($"ScoreModel OK: {G.ScoreModel != null}");
foreach (var shipCounter in shipCounters)
{
if (shipCounter.ShowScore(G.ScoreModel))
await UniTask.Delay(1000);
}
await DisplayScore(G.ScoreModel.Score);
rankAnimation.SetActive(true);
await UniTask.Delay(TimeSpan.FromSeconds(rankAnimationTime));
//показать ui
await ShowInstruction();
//Запустить поллинг
polling = true;
//Запустить таймер
ShowTimer();
WaitTimeoutNExit(this.GetCancellationTokenOnDestroy()).Forget();
}
private void Update()
{
if (!polling) return;
if (In.GetButtonDown(InSignal.DownRight))
{
SceneLoader.LoadScene(menuSceneName);
}
if (In.GetButtonDown(InSignal.UpRight))
{
bool payed = WalletManager.TakeMoney(SettingsManager.GetInt(SettingKey.RevengePrice, 10));
if (payed)
{
SceneLoader.LoadScene(gameplaySceneName);
}
}
}
private void Setup()
{
canvas.worldCamera = CamerasManager.Screen_Camera;
rankAnimation.SetActive(false);
instruction.Init();
HideTimer();
}
private async UniTask DisplayScore(int score)
{
if (score == 0)
{
await UniTask.Delay(1000);
scoreLabel.text = score.ToString("D4");
return;
}
float duration = Mathf.Min((float)score / scorePerSecond, maxDuration);
Debug.Log("Score duration " + duration);
float displayedScore = 0;
while (displayedScore != score)
{
float delta = score / duration * Time.deltaTime;
displayedScore = displayedScore + delta;
displayedScore = Mathf.Min(displayedScore, score);
scoreLabel.text = ((int)displayedScore).ToString("D4");
await UniTask.Yield(PlayerLoopTiming.Update);
}
scoreLabel.text = score.ToString("D4");
}
private async UniTask ShowInstruction()
{
float t = 0;
float startY = instructionPanel.anchoredPosition.y;
while (t < 1)
{
t += Time.deltaTime;
t = Mathf.Min(t, 1);
float y = Mathf.LerpUnclamped(startY, targetY, animationCurve.Evaluate(t));
instructionPanel.anchoredPosition = new Vector2(instructionPanel.anchoredPosition.x, y);
await UniTask.Yield(PlayerLoopTiming.Update);
}
}
private async UniTask WaitTimeoutNExit(CancellationToken token)
{
float timerest = timeout;
while (!token.IsCancellationRequested)
{
UpdateTimer(timerest);
await UniTask.Delay(1000, cancellationToken: token);
timerest -= 1;
if (timerest <= 0)
{
SceneLoader.LoadScene(menuSceneName);
break;
}
}
}
private void ShowTimer()
{
TimerGO.SetActive(true);
UpdateTimer(timeout);
}
private void HideTimer() => TimerGO.SetActive(false);
private void UpdateTimer(float seconds)
{
TimerLabel.text = TimeSpan.FromSeconds(seconds).ToString(@"mm\:ss");
}
}