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

220 lines
6.2 KiB
C#

using Cysharp.Threading.Tasks;
using Lights;
using Periscope;
using System;
using System.Collections.Generic;
using System.Threading;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AwardsController : MonoBehaviour
{
[Header("Boot")]
[SerializeField] private Canvas canvas;
[SerializeField] private Canvas vrCanvas;
[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;
[SerializeField] private AudioClip click;
[SerializeField] private AudioClip type;
[Header("Анимация ранга")]
[SerializeField] private Image RankImage;
[SerializeField] private TextMeshProUGUI RankLabel;
[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;
private CancellationTokenSource timerCts;
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));
//напечатать ранг
await DisplayRankName();
//показать ui
await ShowInstruction();
//Запустить поллинг
polling = true;
//Запустить таймер
timerCts = new CancellationTokenSource();
ShowTimer();
WaitTimeoutNExit(timerCts.Token).Forget();
}
private void Update()
{
if (!polling) return;
if (In.GetButtonDown(InSignal.DownRight))
{
CancelToken();
SceneLoader.LoadScene(menuSceneName);
}
if (In.GetButtonDown(InSignal.UpRight))
{
bool payed = WalletManager.TryTakeMoney(SettingsManager.GetInt(SettingKey.RevengePrice, 10));
if (payed)
{
CountersSystem.Increment(CountersSystem.CounterType.TotalStarts);
CountersSystem.Increment(CountersSystem.CounterType.StartsFromRevenge);
CancelToken();
SceneLoader.LoadScene(gameplaySceneName);
}
}
}
private void CancelToken()
{
timerCts?.Cancel();
timerCts?.Dispose();
timerCts = null;
}
private void Setup()
{
canvas.worldCamera = CamerasManager.Screen_Camera;
vrCanvas.worldCamera = CamerasManager.VR_Camera;
rankAnimation.SetActive(false);
instruction.Init();
HideTimer();
RankImage.sprite = G.Rank.Sprite;
PeriscopeManager.MoveUpToEnd();
LightSystem.SetAllIndicators(1);
}
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");
SoundManager.PlayUi(click);
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;
}
}
Debug.Log("Таймер убит");
}
private async UniTask DisplayRankName()
{
string rankName = G.Rank.Name;
RankLabel.text = "";
for (int i = 0; i < rankName.Length; i++)
{
RankLabel.text += rankName[i];
SoundManager.PlayUi(type);
await UniTask.Delay(150);
}
}
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");
}
}