Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- завершен спринт 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
180 lines
6.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|