Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- Добавлена система баланса игры (BalanceManager) для управления внутриигровой валютой - Баланс начисляется за импульсы оплаты и списывается за начало/продолжение игры - При старте игры весь внесенный баланс списывается, а жизни начисляются в соответствии с количеством оплат - Добавлены проверки достаточности баланса для начала и продолжения игры - Интегрирован BalanceManager с PaymentManager и GameManager - Исправлен баг с возможностью снятия паузы при показе баннера проигрыша/победы - Добавлена блокировка переключения паузы через IsActive флаг в PauseMenu - Жизни больше не могут уйти в минус при повторной смерти во время показа баннера - Настройки стоимости импульса, начала и продолжения игры берутся из SettingsManager
127 lines
3.8 KiB
C#
127 lines
3.8 KiB
C#
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.EventSystems;
|
||
using UnityEngine.UI;
|
||
|
||
namespace RR.Common.Settings.UI
|
||
{
|
||
/// <summary>
|
||
/// Компонент-Selectable для элемента настроек с выбором значения стрелками влево/вправо.
|
||
/// Работает на одном префабе вместе с SettingUIItem.
|
||
/// </summary>
|
||
public class ValueSelectorRow : Selectable, IMoveHandler
|
||
{
|
||
[Header("References")]
|
||
[SerializeField] private TMP_Text valueText;
|
||
|
||
private SettingEntry _entry;
|
||
private int _currentValue;
|
||
private int _step = 1;
|
||
|
||
public void Setup(SettingEntry entry, int currentValue)
|
||
{
|
||
if (entry == null)
|
||
{
|
||
Debug.LogError("[ValueSelectorRow] Cannot setup with null entry!");
|
||
return;
|
||
}
|
||
|
||
_entry = entry;
|
||
|
||
// Валидация step
|
||
if (entry.intStep <= 0)
|
||
{
|
||
Debug.LogWarning($"[ValueSelectorRow] Invalid step {entry.intStep} for key {entry.key}, using 1");
|
||
_step = 1;
|
||
}
|
||
else
|
||
{
|
||
_step = entry.intStep;
|
||
}
|
||
|
||
_currentValue = Mathf.Clamp(currentValue, entry.minInt, entry.maxInt);
|
||
UpdateUI();
|
||
}
|
||
|
||
public new void OnMove(AxisEventData eventData)
|
||
{
|
||
if (_entry == null || !IsInteractable())
|
||
{
|
||
// Пробрасываем событие к базовому классу для стандартной навигации
|
||
base.OnMove(eventData);
|
||
return;
|
||
}
|
||
|
||
switch (eventData.moveDir)
|
||
{
|
||
case MoveDirection.Left:
|
||
DecreaseValue();
|
||
eventData.Use();
|
||
break;
|
||
|
||
case MoveDirection.Right:
|
||
IncreaseValue();
|
||
eventData.Use();
|
||
break;
|
||
|
||
case MoveDirection.Up:
|
||
case MoveDirection.Down:
|
||
// Пробрасываем вертикальную навигацию к базовому классу
|
||
base.OnMove(eventData);
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void DecreaseValue()
|
||
{
|
||
int newValue = Mathf.Max(_entry.minInt, _currentValue - _step);
|
||
if (newValue != _currentValue)
|
||
{
|
||
SetValue(newValue);
|
||
}
|
||
}
|
||
|
||
private void IncreaseValue()
|
||
{
|
||
int newValue = Mathf.Min(_entry.maxInt, _currentValue + _step);
|
||
if (newValue != _currentValue)
|
||
{
|
||
SetValue(newValue);
|
||
}
|
||
}
|
||
|
||
private void UpdateUI()
|
||
{
|
||
if (valueText != null)
|
||
valueText.text = _currentValue.ToString();
|
||
}
|
||
|
||
public void SetValue(int value)
|
||
{
|
||
if (_entry == null)
|
||
return;
|
||
|
||
int clampedValue = Mathf.Clamp(value, _entry.minInt, _entry.maxInt);
|
||
if (clampedValue != _currentValue)
|
||
{
|
||
_currentValue = clampedValue;
|
||
UpdateUI();
|
||
|
||
// Сохраняем изменения через SettingsManager
|
||
var manager = SettingsManager.Instance;
|
||
if (manager != null)
|
||
{
|
||
manager.SetInt(_entry.key, _currentValue);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("[ValueSelectorRow] SettingsManager.Instance is null!");
|
||
}
|
||
}
|
||
}
|
||
|
||
public string Key => _entry?.key;
|
||
}
|
||
}
|
||
|