Danro/Assets/Scripts/UI/MainMenu.cs
Danil Iarosh 78d7679e2b
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
feat(prizes, ui): complete Mar 24-Apr 2 sprint ahead of schedule
- завершен спринт 24 марта - 2 апреля с опережением плана и закрытием задач раньше срока
- расширена и стабилизирована система призов:
  добавлены и доработаны QR-tier конфиги, новые типы и модели данных,
  сохранение `qrCodes` в `prizes.json`, fallback-логика и синхронизация
  через `PrizeSystemManager`, `PrizeDatabase` и `LevelPrizeConfig`
- переработан flow настройки QR-призов:
  добавлены `QRCodeSettingsModal` и связанный UI-код,
  разнесены короткий текст приза и полный текст сообщения,
  добавлены шаблоны форматирования, корректная подстановка текста
  в QR и в UI-модалках, а также сохранение конфигурации между запусками
- доработан flow суперприза и текстовых настроек:
  добавлены fallback-правила показа, корректная обработка пустых строк
  и строк из одних пробелов, обновлены binders и показ текста в меню
- реализована и обновлена отдельная настройка витрины:
  добавлена `PrizeStandSettingsModal`, обновлена навигация строк,
  логика выбора ячейки и порогов очков, циклический выбор ячеек,
  ускорение изменения значений и исправления для keyboard/gamepad UX
- доработана игровая модалка витрины `PrizeStandModal`:
  добавлен вывод очков игрока, форматируемый текст счета,
  улучшено отображение ячеек и связанная логика выбора приза
- исправлен подсчет очков и интеграция с prize flow:
  `ScoreSystem` переведен на событийное обновление текущего счета,
  добавлены `CurrentScore`, `CurrentScoreChanged` и корректный display score,
  витрина и связанные UI-элементы теперь получают актуальные очки,
  а не нулевые или несвоевременные preview-значения
- переработаны модальные окна и навигация UI:
  улучшены `Modal`, `ModalManager`, `UIRowPointer`, `RulesModal`,
  `QRCodeModal`, `PrizeStandModal`, `LevelPrizeSettingsModal` и др.,
  чтобы фокус, указатель и submit работали консистентно без мыши
- обновлен win/prize UI:
  доработаны `WinBannerController`, `GameEndUIController`,
  `MainMenu`, `QRCodeUIController`, `TopPanelTextController` и настройки UI,
  улучшены тексты баннеров, отображение призов и итогового счета
- обновлены сцены и ассеты под новый flow:
  `MainMenu`, `Level UI`, prefab'ы строк настроек и кнопок,
  глобальные префабы, шрифты TMP, иконки, recovery-данные и ресурсы UI
- добавлены вспомогательные UI-компоненты и служебные скрипты:
  `ButtonTextFocusColor`, `SelectableDescriptionTarget`, `QRTier`
  и другие изменения, поддерживающие новый конфигурируемый prize UI
2026-04-01 12:47:17 +03:00

180 lines
6.1 KiB
C#

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using RR.Game2D.Core.Managers;
using RR.Common.Managers;
using RR.Common.Settings;
namespace RR.Common.UI
{
public class MainMenu : MonoBehaviour
{
[Header("Кнопки")]
[SerializeField] private Button newGameButton;
[SerializeField] private Button quitButton;
[Header("Автовыбор при загрузке")]
[SerializeField] private Selectable defaultSelectable;
[Tooltip("Задержка перед автовыбором элемента (сек)")]
[SerializeField] private float selectDelay = 1f;
[Header("Тексты")]
[SerializeField] private TextMeshProUGUI paymentText;
[SerializeField] private TextMeshProUGUI supportNumberText;
[SerializeField] private TextMeshProUGUI superPrizeText;
[Header("Форматы текстов")]
[SerializeField] private string supportNumberFormat = "{0}";
[SerializeField] private string superPrizeFormat = "{0}";
private Managers.BalanceManager _balanceManager;
private SettingsManager _settingsManager;
private void Start()
{
_balanceManager = Managers.BalanceManager.Instance;
_settingsManager = SettingsManager.Instance;
Bootstrap();
if (Application.platform == RuntimePlatform.WebGLPlayer)
{
quitButton.gameObject.SetActive(false);
}
if (_balanceManager != null)
_balanceManager.OnBalanceChanged.AddListener(OnBalanceChanged);
if (_settingsManager != null)
{
_settingsManager.OnSettingsLoaded += OnSettingsChanged;
_settingsManager.OnSettingsSaved += OnSettingsChanged;
// Обновляем тексты сразу при старте
UpdateTextsFromSettings();
}
// Автовыбор элемента при загрузке сцены
if (defaultSelectable != null)
StartCoroutine(SelectAfterDelay());
}
private IEnumerator SelectAfterDelay()
{
yield return new WaitForSeconds(selectDelay);
if (defaultSelectable != null)
defaultSelectable.Select();
}
private void OnDestroy()
{
if (_balanceManager != null)
_balanceManager.OnBalanceChanged.RemoveListener(OnBalanceChanged);
if (_settingsManager != null)
{
_settingsManager.OnSettingsLoaded -= OnSettingsChanged;
_settingsManager.OnSettingsSaved -= OnSettingsChanged;
}
}
/// <summary>
/// Метод для загрузки элементов сцены.
/// Вешает события на кнопки
/// </summary>
private void Bootstrap()
{
if (newGameButton)
{
newGameButton.onClick.AddListener(OnNewGame);
// Устанавливаем начальное состояние кнопки
UpdatePlayButtonState();
}
if (quitButton) quitButton.onClick.AddListener(OnQuit);
}
/// <summary>
/// Метод начала новой игры
/// </summary>
private static void OnNewGame()
{
GameManager.Instance.NewGame();
}
/// <summary>
/// Метод выхода из игры
/// </summary>
private static void OnQuit()
{
Application.Quit();
}
private void OnBalanceChanged(int balance)
{
UpdatePlayButtonState();
}
private void OnSettingsChanged()
{
UpdatePlayButtonState();
UpdateTextsFromSettings();
}
private void UpdateTextsFromSettings()
{
if (_settingsManager == null) return;
// Обновляем номер поддержки
if (supportNumberText != null)
{
string supportNumber = _settingsManager.GetString("payment.supportNumber");
supportNumberText.text = string.Format(supportNumberFormat, supportNumber);
}
// Обновляем описание суперприза
if (superPrizeText != null)
{
bool showBigPrizeText = _settingsManager.GetBool("prizes.showBigPrizeText");
superPrizeText.gameObject.SetActive(showBigPrizeText);
if (!showBigPrizeText)
{
return;
}
string superPrize = _settingsManager.GetString("prizes.bigPrize");
if (string.IsNullOrWhiteSpace(superPrize))
{
PrizeSystemManager prizeSystemManager = PrizeSystemManager.Instance;
if (prizeSystemManager != null)
{
superPrize = prizeSystemManager.GetPreferredQRCodePrizeText();
}
}
superPrizeText.text = string.Format(superPrizeFormat, superPrize);
}
}
private void UpdatePlayButtonState()
{
if (!newGameButton) return;
// Проверяем бесплатную игру
if (_settingsManager != null && _settingsManager.GetBool("payment.freeGame"))
{
newGameButton.interactable = true;
paymentText.gameObject.SetActive(false);
return;
}
// Проверяем баланс через BalanceManager
bool canStartGame = _balanceManager != null && _balanceManager.CanStartGame();
newGameButton.interactable = canStartGame;
paymentText.gameObject.SetActive(!canStartGame);
}
}
}