using System; using UnityEngine; public class TextInput : MonoBehaviour { public event Action 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(); } }