157 lines
4.4 KiB
C#

using System;
using UnityEngine;
public class TextInput : MonoBehaviour
{
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;
private float switchButtonPressedTime = 0;
private float letterSwitchSpeed = 0;
private float switchDelayRest = 1;
private int _slotIndex = 0;
private LetterSlot[] _slots;
private LetterSlot _activeSlot => _slots[_slotIndex];
private bool completionRequested = false;
private void Start()
{
string initial = PlayerPrefs.GetString(PrefsKeyVault.NUMBER_TECH, "");
Initialize(11, Alphabets.DIGITS, initial);
}
public void Initialize(int cellsAmount, string alphabet, string initialString = "")
{
Generate(cellsAmount, alphabet);
InitializeSlots(initialString);
}
private void Update()
{
int dir_h = In.GetAxis(Axis.Horizontal, JoystickSide.Both, InteractMode.Discrete);
SwitchSlot(dir_h);
int dir_v = In.GetAxis(Axis.Vertical, JoystickSide.Both, InteractMode.Continious);
SwitchLetter(dir_v);
completionRequested = In.GetButtonAnyPlayer(PlayerAction.action);
if (completionRequested)
Complete();
}
private void Complete()
{
string result = CollectText();
OnComplete?.Invoke(result);
gameObject.SetActive(false);
}
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);
_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;
}
private string CollectText()
{
System.Text.StringBuilder sb = new();
foreach (var slot in _slots)
sb.Append(slot.Symbol);
return sb.ToString().Trim();
}
}