580 lines
22 KiB
C#
580 lines
22 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
|
||
/// <summary>
|
||
/// Отвечает за отображение панели GameOver и анимацию кнопок
|
||
/// </summary>
|
||
public class GameOverUI : MonoBehaviour
|
||
{
|
||
[SerializeField] private int playerId;
|
||
[SerializeField] private GameManager gameManager;
|
||
|
||
[Header("UI Elements")]
|
||
[SerializeField] private Button replayButton;
|
||
[SerializeField] private Button continueButton;
|
||
[SerializeField] private Button menuButton; // Кнопка меню
|
||
[SerializeField] private Button claimPrizeButton; // Кнопка "Забрать приз" (показывается вместо меню при наличии приза)
|
||
[SerializeField] private GameOver gameOverStatusImage; // Надпись победы/поражения (GameOver на firstImage)
|
||
[SerializeField] private GameOver panelBackground; // Фон панели (GameOver на самой панели)
|
||
[SerializeField] private GameOver medalSwitcher; // Медальон (GameOver на secondImage)
|
||
[SerializeField] private TMP_Text notEnoughMoneyText;
|
||
[SerializeField] private TMP_Text revengeTimerText; // текст таймера реванша (60 сек)
|
||
[SerializeField] private TMP_Text replayPriceText; // текст цены реванша со скидкой (отдельный)
|
||
|
||
[Header("Animation Settings")]
|
||
[SerializeField] private Image firstImage; // Картинка надписи победы/поражения
|
||
[SerializeField] private Image secondImage; // Медальон
|
||
[SerializeField] private float popDuration = 0.3f; // Длительность "попапа" в секундах
|
||
[SerializeField] private float popScale = 1.5f; // Максимальный масштаб при "попапе"
|
||
[SerializeField] private float delayBetweenElements = 0.15f; // Задержка между появлением элементов
|
||
[SerializeField] private float buttonSlideDuration = 0.25f; // Длительность слайда кнопки
|
||
[SerializeField] private float buttonSlideOffset = 500f; // Смещение по позиции (начальное)
|
||
[SerializeField] private float pulseScale = 1.06f; // Насколько увеличивается надпись при пульсации
|
||
[SerializeField] private float pulseDuration = 1.4f; // Длительность одного цикла пульсации
|
||
[SerializeField] private float menuButtonSoloOffsetX = -100f; // Сдвиг кнопки "Меню" влево, когда нет второй кнопки (5-й бот)
|
||
|
||
private Coroutine showAnimationCoroutine;
|
||
private Coroutine pulseCoroutine;
|
||
private Coroutine revengeTimerCoroutine;
|
||
private Vector2 replayButtonOriginalPos;
|
||
private Vector2 continueButtonOriginalPos;
|
||
private Vector2 menuButtonOriginalPos;
|
||
private bool positionsCached;
|
||
private bool eventsSubscribed;
|
||
|
||
// CanvasGroup для "прозрачности" кнопок (не меняем activeSelf)
|
||
private CanvasGroup replayCg;
|
||
private CanvasGroup continueCg;
|
||
private CanvasGroup menuCg;
|
||
|
||
// Для сохранения interactable в UpdateButtons между вызовами метода
|
||
private bool lastIsBotGame;
|
||
private bool lastIsWin;
|
||
|
||
/// <summary>Приз, который можно забрать кнопкой "Забрать приз".</summary>
|
||
private Prize currentPendingPrize;
|
||
|
||
private void OnEnable()
|
||
{
|
||
CreditSystem.OnInitialize += Subscribe;
|
||
|
||
if (!eventsSubscribed && (CreditSystem.onCoinAdded != null || CreditSystem.onCoinRemoved != null))
|
||
Subscribe();
|
||
|
||
EnsureCanvasGroups();
|
||
}
|
||
|
||
private void OnDisable()
|
||
{
|
||
if (eventsSubscribed)
|
||
{
|
||
if (CreditSystem.onCoinAdded != null) CreditSystem.onCoinAdded.RemoveListener(HandleCoinsChanged);
|
||
if (CreditSystem.onCoinRemoved != null) CreditSystem.onCoinRemoved.RemoveListener(HandleCoinsChanged);
|
||
eventsSubscribed = false;
|
||
}
|
||
|
||
CreditSystem.OnInitialize -= Subscribe;
|
||
}
|
||
|
||
private void EnsureCanvasGroups()
|
||
{
|
||
replayCg = EnsureCanvasGroup(replayButton);
|
||
continueCg = EnsureCanvasGroup(continueButton);
|
||
menuCg = EnsureCanvasGroup(menuButton);
|
||
}
|
||
|
||
private static CanvasGroup EnsureCanvasGroup(Button b)
|
||
{
|
||
if (b == null) return null;
|
||
var cg = b.GetComponent<CanvasGroup>();
|
||
if (cg == null) cg = b.gameObject.AddComponent<CanvasGroup>();
|
||
return cg;
|
||
}
|
||
|
||
private void Subscribe()
|
||
{
|
||
if (eventsSubscribed) return;
|
||
|
||
if (CreditSystem.onCoinAdded != null) CreditSystem.onCoinAdded.AddListener(HandleCoinsChanged);
|
||
if (CreditSystem.onCoinRemoved != null) CreditSystem.onCoinRemoved.AddListener(HandleCoinsChanged);
|
||
|
||
eventsSubscribed = true;
|
||
}
|
||
|
||
private void HandleCoinsChanged(int playerID, int newAmount)
|
||
{
|
||
// Обновляем кнопки только если изменились монеты именно этого игрока или его оппонента
|
||
int oponentId = playerId == 1 ? 2 : 1;
|
||
if (playerID == playerId || playerID == oponentId)
|
||
{
|
||
UpdateButtons();
|
||
}
|
||
}
|
||
|
||
public void Show(bool isWin, bool isBotGame, Prize pendingPrize = null)
|
||
{
|
||
lastIsWin = isWin;
|
||
lastIsBotGame = isBotGame;
|
||
currentPendingPrize = pendingPrize;
|
||
|
||
// Останавливаем старую анимацию если она ещё идёт
|
||
if (showAnimationCoroutine != null)
|
||
StopCoroutine(showAnimationCoroutine);
|
||
|
||
if (pulseCoroutine != null)
|
||
{
|
||
StopCoroutine(pulseCoroutine);
|
||
pulseCoroutine = null;
|
||
}
|
||
|
||
if (revengeTimerCoroutine != null)
|
||
{
|
||
StopCoroutine(revengeTimerCoroutine);
|
||
revengeTimerCoroutine = null;
|
||
}
|
||
|
||
if (revengeTimerText != null)
|
||
revengeTimerText.gameObject.SetActive(false);
|
||
|
||
if (replayPriceText != null)
|
||
replayPriceText.gameObject.SetActive(false);
|
||
|
||
EnsureCanvasGroups();
|
||
|
||
// 1) Сразу определяем, какие кнопки видимые
|
||
ApplyButtonVisibility(isWin, isBotGame, pendingPrize);
|
||
|
||
// 2) Переключаем спрайты
|
||
if (panelBackground != null)
|
||
panelBackground.GameOverSwitch(isWin);
|
||
|
||
if (gameOverStatusImage != null)
|
||
gameOverStatusImage.GameOverSwitch(isWin);
|
||
|
||
if (medalSwitcher != null)
|
||
medalSwitcher.GameOverSwitch(isWin);
|
||
|
||
// 3) Виндиста
|
||
if (isBotGame && !isWin)
|
||
VindistaController.Instance?.SetDiscountMode(true, playerId);
|
||
|
||
UpdateButtons();
|
||
|
||
if (gameManager != null && gameManager.uiManager != null)
|
||
gameManager.uiManager.OnPanelChanged?.Invoke();
|
||
|
||
PrepVisualsForAnimation();
|
||
|
||
int credits = CreditSystem.GetPlayerCredits(playerId);
|
||
showAnimationCoroutine = StartCoroutine(ShowElementsSequence(isWin, isBotGame, credits));
|
||
|
||
// Таймер реванша — только при поражении в игре с ботом
|
||
if (isBotGame && !isWin)
|
||
revengeTimerCoroutine = StartCoroutine(RevengeTimerCoroutine());
|
||
}
|
||
|
||
private void ApplyButtonVisibility(bool isWin, bool isBotGame, Prize pendingPrize = null)
|
||
{
|
||
bool isAtFinalBoss = gameManager != null && gameManager.currentBotLevel >= 4;
|
||
|
||
// Победа над финальным боссом — только кнопка меню
|
||
// Победа в PvE (не финал) — кнопка "Продолжить"
|
||
// Всё остальное (поражение, PvP) — кнопка "Реванш"
|
||
bool showContinueButton = isBotGame && isWin && !isAtFinalBoss;
|
||
bool showReplayButton = !(isBotGame && isWin); // скрыт при любой победе в PvE
|
||
bool showClaimPrize = pendingPrize != null; // кнопка "Забрать приз" вместо "Меню"
|
||
|
||
if (replayButton != null) replayButton.gameObject.SetActive(showReplayButton);
|
||
if (continueButton != null) continueButton.gameObject.SetActive(showContinueButton);
|
||
if (menuButton != null) menuButton.gameObject.SetActive(!showClaimPrize); // скрываем "Меню" если есть приз
|
||
if (claimPrizeButton != null) claimPrizeButton.gameObject.SetActive(showClaimPrize); // показываем "Забрать приз"
|
||
UpdateNotEnoughMoneyText(false);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Подготовка всех визуальных элементов: делаем начально всё с alpha=0 и смещен вниз,
|
||
/// при этом activeSelf не меняем.
|
||
/// </summary>
|
||
private void PrepVisualsForAnimation()
|
||
{
|
||
CacheButtonPositionsIfNeeded();
|
||
|
||
// Картинки: scale=0
|
||
if (firstImage != null) firstImage.transform.localScale = Vector3.zero;
|
||
if (secondImage != null) secondImage.transform.localScale = Vector3.zero;
|
||
|
||
// Кнопки: alpha=0 и сдвиг вниз (только если активны)
|
||
PrepButtonVisual(replayButton, replayCg, replayButtonOriginalPos);
|
||
PrepButtonVisual(continueButton, continueCg, continueButtonOriginalPos);
|
||
// Анимируем либо menuButton, либо claimPrizeButton — тот что активен
|
||
Button activeMenuBtn = (claimPrizeButton != null && claimPrizeButton.gameObject.activeSelf)
|
||
? claimPrizeButton : menuButton;
|
||
var activeCg = EnsureCanvasGroup(activeMenuBtn);
|
||
PrepButtonVisual(activeMenuBtn, activeCg, GetMenuButtonTargetPos());
|
||
}
|
||
|
||
private void CacheButtonPositionsIfNeeded()
|
||
{
|
||
if (positionsCached) return;
|
||
|
||
if (replayButton != null)
|
||
{
|
||
var rt = replayButton.GetComponent<RectTransform>();
|
||
if (rt != null) replayButtonOriginalPos = rt.anchoredPosition;
|
||
}
|
||
|
||
if (continueButton != null)
|
||
{
|
||
var rt = continueButton.GetComponent<RectTransform>();
|
||
if (rt != null) continueButtonOriginalPos = rt.anchoredPosition;
|
||
}
|
||
|
||
if (menuButton != null)
|
||
{
|
||
var rt = menuButton.GetComponent<RectTransform>();
|
||
if (rt != null) menuButtonOriginalPos = rt.anchoredPosition;
|
||
}
|
||
|
||
positionsCached = true;
|
||
}
|
||
|
||
private void PrepButtonVisual(Button b, CanvasGroup cg, Vector2 original)
|
||
{
|
||
if (b == null || cg == null) return;
|
||
if (!b.gameObject.activeSelf) return;
|
||
|
||
cg.alpha = 0f;
|
||
|
||
var rt = b.GetComponent<RectTransform>();
|
||
if (rt != null)
|
||
rt.anchoredPosition = new Vector2(original.x, original.y - buttonSlideOffset);
|
||
}
|
||
|
||
private IEnumerator ShowElementsSequence(bool isWin, bool isBotGame, int credits)
|
||
{
|
||
// 1. Первая картинка
|
||
if (firstImage != null)
|
||
{
|
||
yield return StartCoroutine(PopInElement(firstImage.transform));
|
||
yield return new WaitForSeconds(delayBetweenElements);
|
||
}
|
||
|
||
// 2. Вторая картинка
|
||
if (secondImage != null)
|
||
{
|
||
yield return StartCoroutine(PopInElement(secondImage.transform));
|
||
yield return new WaitForSeconds(delayBetweenElements);
|
||
}
|
||
|
||
// 3. Кнопки действия
|
||
if (isBotGame)
|
||
yield return StartCoroutine(ShowBotGameButtonsAnimated(isWin, credits));
|
||
else
|
||
yield return StartCoroutine(ShowPvPGameButtonsAnimated(credits));
|
||
|
||
// 4. Меню
|
||
yield return StartCoroutine(ShowMenuButtonAnimated());
|
||
|
||
// 5. Пульсация надписи победы/поражения
|
||
if (firstImage != null)
|
||
pulseCoroutine = StartCoroutine(PulseLoop(firstImage.transform));
|
||
}
|
||
|
||
private IEnumerator PulseLoop(Transform element)
|
||
{
|
||
float half = pulseDuration * 0.5f;
|
||
|
||
while (element != null)
|
||
{
|
||
// Плавно увеличиваем
|
||
float elapsed = 0f;
|
||
while (elapsed < half)
|
||
{
|
||
elapsed += Time.deltaTime;
|
||
float t = Mathf.SmoothStep(0f, 1f, elapsed / half);
|
||
element.localScale = Vector3.one * Mathf.Lerp(1f, pulseScale, t);
|
||
yield return null;
|
||
}
|
||
|
||
// Плавно уменьшаем
|
||
elapsed = 0f;
|
||
while (elapsed < half)
|
||
{
|
||
elapsed += Time.deltaTime;
|
||
float t = Mathf.SmoothStep(0f, 1f, elapsed / half);
|
||
element.localScale = Vector3.one * Mathf.Lerp(pulseScale, 1f, t);
|
||
yield return null;
|
||
}
|
||
}
|
||
}
|
||
|
||
private IEnumerator PopInElement(Transform element)
|
||
{
|
||
float elapsed = 0f;
|
||
Vector3 targetScale = Vector3.one;
|
||
|
||
while (elapsed < popDuration)
|
||
{
|
||
elapsed += Time.deltaTime;
|
||
float progress = elapsed / popDuration;
|
||
|
||
float scale;
|
||
if (progress < 0.4f)
|
||
{
|
||
scale = Mathf.Lerp(0f, popScale, progress / 0.4f);
|
||
}
|
||
else
|
||
{
|
||
float returnProgress = (progress - 0.4f) / 0.6f;
|
||
scale = Mathf.Lerp(popScale, 1f, returnProgress);
|
||
}
|
||
|
||
element.localScale = Vector3.one * scale;
|
||
yield return null;
|
||
}
|
||
|
||
element.localScale = targetScale;
|
||
}
|
||
|
||
private IEnumerator SlideInButton(RectTransform rectTransform, Vector2 targetPosition)
|
||
{
|
||
Vector2 startPosition = rectTransform.anchoredPosition;
|
||
float elapsed = 0f;
|
||
|
||
while (elapsed < buttonSlideDuration)
|
||
{
|
||
elapsed += Time.deltaTime;
|
||
float progress = elapsed / buttonSlideDuration;
|
||
|
||
float easedProgress = 1f - Mathf.Pow(1f - progress, 3f);
|
||
|
||
rectTransform.anchoredPosition = Vector2.Lerp(startPosition, targetPosition, easedProgress);
|
||
yield return null;
|
||
}
|
||
|
||
rectTransform.anchoredPosition = targetPosition;
|
||
}
|
||
|
||
private IEnumerator FadeIn(CanvasGroup cg)
|
||
{
|
||
if (cg == null) yield break;
|
||
|
||
float elapsed = 0f;
|
||
while (elapsed < buttonSlideDuration)
|
||
{
|
||
elapsed += Time.deltaTime;
|
||
float t = Mathf.Clamp01(elapsed / buttonSlideDuration);
|
||
cg.alpha = t;
|
||
yield return null;
|
||
}
|
||
cg.alpha = 1f;
|
||
}
|
||
|
||
private IEnumerator SlideAndFadeIn(Button b, CanvasGroup cg, Vector2 targetPos)
|
||
{
|
||
if (b == null || cg == null) yield break;
|
||
if (!b.gameObject.activeSelf) yield break;
|
||
|
||
var rt = b.GetComponent<RectTransform>();
|
||
if (rt == null)
|
||
{
|
||
cg.alpha = 1f;
|
||
yield break;
|
||
}
|
||
|
||
// Одновременно: slide + fade
|
||
Coroutine slide = StartCoroutine(SlideInButton(rt, targetPos));
|
||
Coroutine fade = StartCoroutine(FadeIn(cg));
|
||
yield return slide;
|
||
yield return fade;
|
||
}
|
||
|
||
private IEnumerator ShowBotGameButtonsAnimated(bool isWin, int credits)
|
||
{
|
||
if (isWin)
|
||
{
|
||
// Continue: следующий уровень бесплатный (рефанд + оплата = 0), всегда доступна
|
||
if (continueButton != null && continueButton.gameObject.activeSelf)
|
||
{
|
||
continueButton.interactable = true;
|
||
yield return StartCoroutine(SlideAndFadeIn(continueButton, continueCg, continueButtonOriginalPos));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (replayButton != null && replayButton.gameObject.activeSelf)
|
||
{
|
||
int fullPrice = CreditSystem.BotGamePrice;
|
||
int replayPrice = CreditSystem.GetEffectiveBotPrice(isReplay: true);
|
||
// В режиме бесплатной игры кнопка всегда доступна
|
||
replayButton.interactable = CreditSystem.IsFreePlay || credits >= replayPrice;
|
||
|
||
var txt = replayButton.GetComponentInChildren<TMP_Text>();
|
||
if (txt != null)
|
||
txt.text = "Реванш!";
|
||
|
||
// Цена со скидкой — в отдельный текст
|
||
if (replayPriceText != null)
|
||
{
|
||
if (replayPrice < fullPrice)
|
||
replayPriceText.text = $"Реванш за <s>{fullPrice} р.</s> {replayPrice} р.";
|
||
else
|
||
replayPriceText.text = $"Реванш за {replayPrice} р.";
|
||
|
||
replayPriceText.gameObject.SetActive(true);
|
||
}
|
||
|
||
yield return StartCoroutine(SlideAndFadeIn(replayButton, replayCg, replayButtonOriginalPos));
|
||
}
|
||
}
|
||
}
|
||
|
||
private IEnumerator ShowPvPGameButtonsAnimated(int credits)
|
||
{
|
||
if (replayButton != null && replayButton.gameObject.activeSelf)
|
||
{
|
||
int oponentId = playerId == 1 ? 2 : 1;
|
||
int oponentCredits = CreditSystem.GetPlayerCredits(oponentId);
|
||
int price = CreditSystem.PlayerGamePrice;
|
||
|
||
// В режиме бесплатной игры кнопка всегда доступна
|
||
// Проверяем в сумме — игра возможна если вместе хватает на полную стоимость
|
||
replayButton.interactable = CreditSystem.IsFreePlay ||
|
||
credits + oponentCredits >= price;
|
||
|
||
var txt = replayButton.GetComponentInChildren<TMP_Text>();
|
||
if (txt != null) txt.text = "Еще раз!";
|
||
|
||
yield return StartCoroutine(SlideAndFadeIn(replayButton, replayCg, replayButtonOriginalPos));
|
||
}
|
||
}
|
||
|
||
private IEnumerator ShowMenuButtonAnimated()
|
||
{
|
||
// Анимируем активную кнопку — либо "Забрать приз", либо "Меню"
|
||
Button activeBtn = (claimPrizeButton != null && claimPrizeButton.gameObject.activeSelf)
|
||
? claimPrizeButton : menuButton;
|
||
var activeCg = EnsureCanvasGroup(activeBtn);
|
||
|
||
if (activeBtn != null && activeBtn.gameObject.activeSelf)
|
||
yield return StartCoroutine(SlideAndFadeIn(activeBtn, activeCg, GetMenuButtonTargetPos()));
|
||
}
|
||
|
||
/// <summary>
|
||
/// Возвращает true только если обе кнопки (Реванш/Продолжить) скрыты — только кнопка "Меню".
|
||
/// </summary>
|
||
private bool IsOnlyMenuButtonVisible()
|
||
{
|
||
bool replayVisible = replayButton != null && replayButton.gameObject.activeSelf;
|
||
bool continueVisible = continueButton != null && continueButton.gameObject.activeSelf;
|
||
return !replayVisible && !continueVisible;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Целевая позиция кнопки "Меню": при solo-режиме сдвигаем влево на menuButtonSoloOffsetX.
|
||
/// </summary>
|
||
private Vector2 GetMenuButtonTargetPos()
|
||
{
|
||
if (IsOnlyMenuButtonVisible())
|
||
return new Vector2(menuButtonOriginalPos.x + menuButtonSoloOffsetX, menuButtonOriginalPos.y);
|
||
return menuButtonOriginalPos;
|
||
}
|
||
|
||
public void UpdateButtons()
|
||
{
|
||
int credits = CreditSystem.GetPlayerCredits(playerId);
|
||
int oponentId = playerId == 1 ? 2 : 1;
|
||
int oponentCredits = CreditSystem.GetPlayerCredits(oponentId);
|
||
|
||
// Continue: следующий уровень бесплатный — всегда доступна
|
||
if (continueButton != null && continueButton.gameObject.activeSelf)
|
||
continueButton.interactable = true;
|
||
|
||
if (replayButton != null && replayButton.gameObject.activeSelf)
|
||
{
|
||
// В режиме бесплатной игры кнопка всегда доступна
|
||
if (CreditSystem.IsFreePlay)
|
||
{
|
||
replayButton.interactable = true;
|
||
}
|
||
else if (lastIsBotGame)
|
||
{
|
||
int replayPrice = CreditSystem.GetEffectiveBotPrice(isReplay: true);
|
||
replayButton.interactable = credits >= replayPrice;
|
||
}
|
||
else
|
||
{
|
||
int price = CreditSystem.PlayerGamePrice;
|
||
replayButton.interactable = credits + oponentCredits >= price;
|
||
}
|
||
}
|
||
|
||
// notEnoughMoneyText не используется — вместо него replayPriceText со скидкой
|
||
UpdateNotEnoughMoneyText(false);
|
||
}
|
||
|
||
private void UpdateNotEnoughMoneyText(bool show)
|
||
{
|
||
if (notEnoughMoneyText != null)
|
||
notEnoughMoneyText.gameObject.SetActive(show);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Вызывается кнопкой "Забрать приз". Привязать в Inspector к claimPrizeButton.
|
||
/// </summary>
|
||
public void OnClaimPrizeClicked()
|
||
{
|
||
if (currentPendingPrize == null || gameManager == null) return;
|
||
|
||
Prize prize = currentPendingPrize;
|
||
currentPendingPrize = null;
|
||
|
||
// Ставим флаг — после таймера PrizeReminder вернуть в меню
|
||
var reminder = FindObjectOfType<PrizeReminderPanel>(true);
|
||
if (reminder != null)
|
||
reminder.shouldReturnToMenu = true;
|
||
|
||
if (prize.PrizeType == PrizeType.Special)
|
||
{
|
||
gameManager.uiManager.ShowOverlayAnimated("QRCode", 0f);
|
||
return;
|
||
}
|
||
if (prize.PrizeType == PrizeType.Showcase)
|
||
{
|
||
gameManager.uiManager.ShowOverlayAnimated("PrizeSelection", 0f);
|
||
return;
|
||
}
|
||
|
||
gameManager.uiManager.ShowOverlayAnimated("PrizeReminder", 0f);
|
||
PrizeSystem.GivePrize(prize, playerId);
|
||
}
|
||
|
||
private IEnumerator RevengeTimerCoroutine()
|
||
{
|
||
float remaining = 60f;
|
||
|
||
if (revengeTimerText != null)
|
||
revengeTimerText.gameObject.SetActive(true);
|
||
|
||
while (remaining > 0f)
|
||
{
|
||
if (revengeTimerText != null)
|
||
revengeTimerText.text = Mathf.CeilToInt(remaining).ToString();
|
||
|
||
yield return new WaitForSeconds(1f);
|
||
remaining -= 1f;
|
||
}
|
||
|
||
// Время вышло — скрываем таймер и уходим в меню
|
||
if (revengeTimerText != null)
|
||
revengeTimerText.gameObject.SetActive(false);
|
||
|
||
if (menuButton != null)
|
||
menuButton.onClick.Invoke();
|
||
|
||
revengeTimerCoroutine = null;
|
||
}
|
||
}
|