sea-battle-vr/Assets/Scripts/Awards/AwardsController2.cs
2026-06-15 10:44:13 +03:00

369 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Cysharp.Threading.Tasks;
using RR.UI;
using System;
using System.Collections.Generic;
using System.Threading;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AwardsController2 : MonoBehaviour
{
[Header("Boot")]
[SerializeField] private Canvas canvas;
[SerializeField] private Canvas vrCanvas;
[SerializeField] private float timeout = 120;
[SerializeField] private string menuSceneName = "MenuOneRegime";
[SerializeField] private string gameplaySceneName = "Gameplay";
[Header("Линии и заголовок")]
[SerializeField] private RectTransform linesLayout;
[SerializeField] private float startLinesX = -1920, targetLinesX = 0;
[SerializeField] private AnimationCurve linesCurve;
[Header("Счетчики")]
[SerializeField] private List<AwardsShipCounter> shipCounters;
[SerializeField] private List<AwardsShipCounter> shipCountersVR;
//
[SerializeField] private CanvasGroup destroyedEnemiesCG;
[SerializeField] private CanvasGroup destroyedEnemiesVR;
[SerializeField] AudioClip soundExplosion;
[SerializeField] AudioClip soundShoot;
[Header("Счет")]
[SerializeField] private CanvasGroup scoreCG;
[SerializeField] private CanvasGroup scoreVR;
[SerializeField] private CounterTMP scoreCounter;
[SerializeField] private CounterTMP scoreCounterVR;
[Header("Ранг")]
[SerializeField] private CanvasGroup rankPanelCG;
[SerializeField] private CanvasGroup rankPanelVR;
[SerializeField] private CanvasGroup rankViewCG;
[SerializeField] private CanvasGroup rankViewVR;
[SerializeField] private CanvasGroup ranksTableCG;
[SerializeField] private Image rankImage;
[SerializeField] private Image rankImageVR;
[SerializeField] private TextMeshProUGUI rankLabel;
[SerializeField] private TextMeshProUGUI rankLabelVR;
[SerializeField] private List<RankViewAwards> rankViews;
[Header("До след ранга")]
[SerializeField] private CanvasGroup ToNextRankCG;
[SerializeField] private TextMeshProUGUI ToNextRankScore;
private bool shouldEnableToNextRank = false;
[Header("Инфо панель")]
[SerializeField] private CanvasGroup InfoPanelCG;
[SerializeField] TextMeshProUGUI timerLabel;
[SerializeField] TextMeshProUGUI balanceLabel;
[SerializeField] TextMeshProUGUI continueLabel;
[SerializeField] private CanvasGroup ExitCG;
[SerializeField] private CanvasGroup ContinueCG;
[SerializeField] InputController inputController;
private CancellationTokenSource cts;
private bool Freeplay => SettingsManager.GetBool(SettingKey.Freeplay, false);
private int PriceContinue => SettingsManager.GetInt(SettingKey.RevengePrice, 10);
[SerializeField] Image BgImage;
[SerializeField] private Sprite goodBg;
[SerializeField] private Sprite badBg;
[SerializeField] AudioSource scoreSound;
private void Start()
{
if (!BootstrapperState.MainBootstraped)
{
SceneLoader.LoadScene("Bootstrap");
return;
}
Init();
cts = new();
var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, GameManager.globalCts.Token);
Process(linkedCts.Token).Forget();
}
private void OnApplicationQuit()
{
cts?.Cancel();
cts?.Dispose();
}
private void Init()
{
SetBackgroundByReason(G.EndGameChecker.lastReason);
destroyedEnemiesCG.alpha = 0; destroyedEnemiesVR.alpha = 0;
//инит счетчики
foreach (var shipCounter in shipCounters)
{
shipCounter.SetAlpha(0);
shipCounter.ShowScore(G.ScoreModel);
}
foreach (var shipCounter in shipCountersVR)
{
shipCounter.SetAlpha(0);
shipCounter.ShowScore(G.ScoreModel);
}
scoreCG.alpha = 0;
scoreVR.alpha = 0;
scoreCounter.SetCount(0); scoreCounterVR.SetCount(0);
rankPanelCG.alpha = 0;
rankPanelVR.alpha = 0;
rankViewCG.alpha = 0;
rankViewVR.alpha = 0;
rankImage.sprite = G.Rank.SpriteGreen;
rankImageVR.sprite = G.Rank.SpriteGreen;
rankLabel.text = G.Rank.Name; rankLabelVR.text = G.Rank.Name;
//до след ранга
shouldEnableToNextRank = RankSystem.Instance.HasNextRank(G.ScoreModel.Score);
if (shouldEnableToNextRank)
{
ToNextRankScore.text = RankSystem.Instance.ScoreToNextRank(G.ScoreModel.Score).ToString() + " очков";
}
ToNextRankCG.alpha = 0;
//ини таблицы рангов
ranksTableCG.alpha = 0;
int actualRankIndex = RankSystem.Instance.GetActualRankIndex(G.ScoreModel.Score);
for (int i = 0; i < rankViews.Count; i++)
{
RankSystem.RankInfo rankInfo = RankSystem.Instance.Ranks[i];
float alpha = i > actualRankIndex ? 0.2f : 1f;
bool enableFrame = i == actualRankIndex;
rankViews[i].Configure(alpha, enableFrame, rankInfo.Name, rankInfo.RequiredScore, rankInfo.SpriteGreen);
}
InfoPanelCG.alpha = 0;
canvas.worldCamera = CamerasManager.Screen_Camera;
vrCanvas.worldCamera = CamerasManager.VR_Camera;
}
private void SetBackgroundByReason(EndGameConditionChecker.EndgameReason reason)
{
if (reason == EndGameConditionChecker.EndgameReason.Death)
BgImage.sprite = badBg;
else
BgImage.sprite = goodBg;
}
private async UniTask Process(CancellationToken ct)
{
await ShowLinesAndTitle(1, ct);
await ShowDestroyedEnemies(ct);
await ShowScore(ct);
await ShowRank(ct);
await UniTask.Delay(2000, cancellationToken: ct);
if(shouldEnableToNextRank)
LerpAlpha(0, 1,1, ToNextRankCG, ct).Forget();
RanksAndDestroyedAnimation(ct).Forget();
InstructionsAnimation(ct).Forget();
InitInfoPanel();
await LerpAlpha(0, 1, 1, InfoPanelCG, ct);
ActivateControls();
StartExitByTimerProcess(ct).Forget();
}
private async UniTask ShowLinesAndTitle(float duration, CancellationToken ct)
{
float elapsed = 0;
while (!ct.IsCancellationRequested && elapsed < duration)
{
elapsed += Time.deltaTime;
float t = Mathf.Min(1, elapsed / duration);
float t1 = linesCurve.Evaluate(t);
float x = Mathf.Lerp(startLinesX, targetLinesX, t1);
linesLayout.anchoredPosition = new Vector2(x, linesLayout.localPosition.y);
await UniTask.Yield(ct);
}
if (!ct.IsCancellationRequested)
{
linesLayout.anchoredPosition = new Vector2(targetLinesX, linesLayout.localPosition.y);
}
}
private async UniTask ShowDestroyedEnemies(CancellationToken ct)
{
SoundManager.PlayUi(soundExplosion);
destroyedEnemiesCG.alpha = 1; destroyedEnemiesVR.alpha = 1;
for (int i = 0; i < shipCounters.Count; i++)
{
await UniTask.Delay(500, cancellationToken: ct);
SoundManager.PlayUi(soundShoot);
shipCounters[i].SetAlpha(1); shipCountersVR[i].SetAlpha(1);
}
}
private async UniTask ShowScore(CancellationToken ct)
{
LerpAlpha(0, 1, 5, scoreVR, ct).Forget(); await LerpAlpha(0, 1, 5, scoreCG, ct);
await UniTask.Delay(1000, cancellationToken: ct);
scoreSound.Play();
scoreCounterVR.AnimateScoreChange(0, G.ScoreModel.Score).Forget(); await scoreCounter.AnimateScoreChange(0, G.ScoreModel.Score);
scoreSound.Stop();
}
private async UniTask ShowRank(CancellationToken ct)
{
LerpAlpha(0, 1, 5, rankPanelVR, ct).Forget(); await LerpAlpha(0, 1, 5, rankPanelCG, ct);
await UniTask.Delay(1000, cancellationToken: ct);
SoundManager.PlayUi(soundShoot);
rankViewCG.alpha = 1; rankViewVR.alpha = 1;
}
private async UniTask RanksAndDestroyedAnimation(CancellationToken ct)
{
var descendingGroup = destroyedEnemiesCG;
var ascendingGroup = ranksTableCG;
while (!ct.IsCancellationRequested)
{
await LerpAlpha(1, 0, 1, descendingGroup, ct);
await LerpAlpha(0, 1, 1, ascendingGroup, ct);
await UniTask.Delay(3000, cancellationToken: ct);
if (!ct.IsCancellationRequested)
{
(descendingGroup, ascendingGroup) = (ascendingGroup, descendingGroup);
}
}
}
private async UniTask InstructionsAnimation(CancellationToken ct)
{
var descendingGroup = ContinueCG;
var ascendingGroup = ExitCG;
while (!ct.IsCancellationRequested)
{
await LerpAlpha(1, 0, 1, descendingGroup, ct);
await LerpAlpha(0, 1, 1, ascendingGroup, ct);
await UniTask.Delay(3000, cancellationToken: ct);
if (!ct.IsCancellationRequested)
{
(descendingGroup, ascendingGroup) = (ascendingGroup, descendingGroup);
}
}
}
private void ActivateControls()
{
inputController.Init(startPolling: true);
}
public void InitInfoPanel()
{
UpdateTimer(timeout);
UpdateBalance(WalletManager.Balance);
WalletManager.OnBalanceChanged += UpdateBalance;
balanceLabel.enabled = !Freeplay;
if (Freeplay)
{
continueLabel.text = $"Продолжить\n ";
}
else
{
int price = PriceContinue;
continueLabel.text = $"Продолжить\n{price} {GetValutaPluralized(price)}";
}
}
private async UniTask StartExitByTimerProcess(CancellationToken ct)
{
while(timeout > 0 && !ct.IsCancellationRequested)
{
UpdateTimer(timeout);
timeout -= 1;
await UniTask.Delay(1000, cancellationToken:ct);
}
if(!ct.IsCancellationRequested)
{
ExitMenu();
}
}
public void ExitMenu()
{
cts?.Cancel();
cts?.Dispose();
cts = null;
WalletManager.OnBalanceChanged -= UpdateBalance;
SceneLoader.LoadScene(menuSceneName);
}
public void Resume()
{
if(Freeplay || WalletManager.TryTakeMoney(PriceContinue))
{
cts?.Cancel();
cts?.Dispose();
cts = null;
WalletManager.OnBalanceChanged -= UpdateBalance;
SceneLoader.LoadScene(gameplaySceneName);
}
}
//Helpers
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 string GetValutaPluralized(int balance)
=> SettingsManager.GetString(SettingKey.Valuta, "руб.") == "руб." ? PluralizeUtil.Rubles(balance) : PluralizeUtil.Tokens(balance);
private void UpdateTimer(float timerest)
{
TimeSpan time = TimeSpan.FromSeconds(timerest);
timerLabel.text = $"выход в меню через:\n {time.ToString(@"mm\:ss")}";
}
private void UpdateBalance(int balance)
{
balanceLabel.text = $"баланс:\n{balance} {GetValutaPluralized(WalletManager.Balance)}";
}
}