369 lines
11 KiB
C#
369 lines
11 KiB
C#
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)}";
|
||
}
|
||
} |