sega 826ff5782a Доработать игровые режимы, призы и настройки
Добавить таймеры и шкалы прогресса, расширить призовую систему и контроль остатков, восстановить настройки и обновить таблицу призов главного меню.
2026-09-14 10:47:25 +03:00

168 lines
4.9 KiB
C#

using System;
using UnityEngine;
public class TextInput : MonoBehaviour, IControlable
{
public event Action<string> OnComplete;
[Header("Генерация")]
[SerializeField] private LetterSlot _letterSlotPrefab;
[SerializeField] private RectTransform _cellsRoot;
[Header("Звуки")]
[SerializeField] private AudioClip switchSlotSound;
[SerializeField] private AudioClip switchLetterSound;
[SerializeField] private AudioClip acceptSound;
[SerializeField] private AudioClip openSound;
[Header("Скорость переключения букв")]
[SerializeField] private float MaxSpeedLetterPerSecond = 8;
[SerializeField] private float MinSpeedLetterPerSecond = 3;
[SerializeField] private float MaxSpeedTime = 3;
[SerializeField] private float MinSpeedTime = 0.5f;
[SerializeField] private bool _destroyOnComplete = true;
private float switchButtonPressedTime = 0;
private float letterSwitchSpeed = 0;
private float switchDelayRest = 1;
private int _slotIndex = 0;
private LetterSlot[] _slots;
private bool completionRequested = false;
private bool completeUnpressed = false;
public bool ControlsEnabled { get; set; } = true;
private LetterSlot ActiveSlot => _slots[_slotIndex];
public void Initialize(int cellsAmount, string alphabet, string initialString = "")
{
ControlsEnabled = true;
completionRequested = false;
completeUnpressed = false;
Generate(cellsAmount, alphabet);
InitializeSlots(initialString);
}
public void SetDestroyOnComplete(bool destroyOnComplete)
=> _destroyOnComplete = destroyOnComplete;
public void UpdateControls()
{
int dir_h = In.GetAxis(JoystickSide.Both, InteractMode.Discrete).x;
SwitchSlot(dir_h);
int dir_v = In.GetAxis(JoystickSide.Both, InteractMode.Continious).y;
SwitchLetter(dir_v);
if(In.GetAction(JoystickSide.Both, InteractMode.Continious) == false)
completeUnpressed = true;
completionRequested = In.GetAction(JoystickSide.Both, InteractMode.Continious);
if (completionRequested && completeUnpressed)
Complete();
}
private void Complete()
{
string result = CollectText();
if (string.IsNullOrWhiteSpace(result))
return;
ControlsEnabled = false;
OnComplete?.Invoke(result);
if (_destroyOnComplete)
Destroy(gameObject);
}
private void Generate(int cellsAmount, string alphabet)
{
ClearCells();
_slots = new LetterSlot[cellsAmount];
for (int i = 0; i < cellsAmount; i++)
{
var cell = Instantiate(_letterSlotPrefab, _cellsRoot);
cell.Init(alphabet[0], alphabet);
_slots[i] = cell;
}
_slotIndex = 0;
_slots[_slotIndex].SetSelected(true);
}
private void InitializeSlots(string initialString)
{
for (int i = 0; i < _slots.Length; i++)
_slots[i].SetSymbol(0);
if (string.IsNullOrEmpty(initialString))
return;
int minLength = Mathf.Min(initialString.Length, _slots.Length);
for (int i = 0; i < minLength; i++)
_slots[i].SetSymbol(initialString[i]);
}
public void SwitchSlot(int dir)
{
if (dir == 0) return;
ActiveSlot.SetSelected(false);
_slotIndex = Mathf.Clamp(_slotIndex + dir, 0, _slots.Length - 1);
ActiveSlot.SetSelected(true);
}
public void SwitchLetter(int dir)
{
if (dir == 0)
{
switchDelayRest = 0;
switchButtonPressedTime = 0;
return;
}
if (switchDelayRest < 0)
{
ActiveSlot.ChangeSymbol(dir);
recalculateRest();
}
switchDelayRest -= Time.deltaTime;
switchButtonPressedTime += Time.deltaTime;
void recalculateRest()
{
float k = (MaxSpeedLetterPerSecond - MinSpeedLetterPerSecond)
/ (MaxSpeedTime - MinSpeedTime);
float b = MinSpeedLetterPerSecond - k * MinSpeedTime;
letterSwitchSpeed = k * switchButtonPressedTime + b;
letterSwitchSpeed = Mathf.Clamp(letterSwitchSpeed,
MinSpeedLetterPerSecond,
MaxSpeedLetterPerSecond);
switchDelayRest = 1 / letterSwitchSpeed;
}
}
private void ClearCells()
{
for (int i = _cellsRoot.childCount - 1; i >= 0; i--)
{
var cell = _cellsRoot.GetChild(i).gameObject;
Destroy(cell);
}
_slots = null;
}
public string CollectText()
{
System.Text.StringBuilder sb = new();
foreach (var slot in _slots)
sb.Append(slot.Symbol);
return sb.ToString().Trim();
}
}