using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
///
/// Терминал лифта: ввод 4-значного кода доступа для перехода на 2-й уровень.
///
public class ElevatorKeypadUI : MonoBehaviour
{
private static ElevatorKeypadUI _instance;
public static ElevatorKeypadUI Instance
{
get
{
if (_instance == null)
{
_instance = Object.FindAnyObjectByType(FindObjectsInactive.Include);
}
return _instance;
}
}
[Header("Корневая панель")]
[SerializeField] private GameObject keypadPanelRoot;
[Header("Слоты для отображения цифр")]
[SerializeField] private Text[] digitSlots = new Text[4];
[SerializeField] private Image[] digitSlotBorders = new Image[4];
[Header("Статусная строка")]
[SerializeField] private Text statusText;
[Header("Кнопки клавиатуры")]
[SerializeField] private Button[] numberButtons; // 0..9
[SerializeField] private Button clearButton;
[SerializeField] private Button enterButton;
[SerializeField] private Button exitButton;
[Header("Цвета статуса")]
public Color normalStatusColor = new Color(1.0f, 0.85f, 0.1f, 1.0f);
public Color errorStatusColor = new Color(1.0f, 0.25f, 0.25f, 1.0f);
public Color successStatusColor = new Color(0.2f, 1.0f, 0.4f, 1.0f);
private string enteredCode = "";
private bool isOpen = false;
private bool isLockedSuccess = false;
public bool IsOpen => isOpen;
private void Awake()
{
_instance = this;
if (keypadPanelRoot == null)
keypadPanelRoot = gameObject;
SetupButtons();
}
private void SetupButtons()
{
if (numberButtons != null)
{
for (int i = 0; i < numberButtons.Length; i++)
{
int num = i;
if (numberButtons[i] != null)
{
numberButtons[i].onClick.RemoveAllListeners();
numberButtons[i].onClick.AddListener(() => OnNumberPressed(num));
}
}
}
if (clearButton != null)
{
clearButton.onClick.RemoveAllListeners();
clearButton.onClick.AddListener(OnClearPressed);
}
if (enterButton != null)
{
enterButton.onClick.RemoveAllListeners();
enterButton.onClick.AddListener(OnEnterPressed);
}
if (exitButton != null)
{
exitButton.onClick.RemoveAllListeners();
exitButton.onClick.AddListener(CloseKeypad);
}
}
private int openFrame = -1;
private void Update()
{
if (!isOpen) return;
if (Time.frameCount == openFrame) return;
HandleKeyboardInput();
}
private void HandleKeyboardInput()
{
var keyboard = Keyboard.current;
if (keyboard != null)
{
if (keyboard.escapeKey.wasPressedThisFrame)
{
CloseKeypad();
return;
}
if (!isLockedSuccess)
{
if (keyboard.digit0Key.wasPressedThisFrame || keyboard.numpad0Key.wasPressedThisFrame) OnNumberPressed(0);
else if (keyboard.digit1Key.wasPressedThisFrame || keyboard.numpad1Key.wasPressedThisFrame) OnNumberPressed(1);
else if (keyboard.digit2Key.wasPressedThisFrame || keyboard.numpad2Key.wasPressedThisFrame) OnNumberPressed(2);
else if (keyboard.digit3Key.wasPressedThisFrame || keyboard.numpad3Key.wasPressedThisFrame) OnNumberPressed(3);
else if (keyboard.digit4Key.wasPressedThisFrame || keyboard.numpad4Key.wasPressedThisFrame) OnNumberPressed(4);
else if (keyboard.digit5Key.wasPressedThisFrame || keyboard.numpad5Key.wasPressedThisFrame) OnNumberPressed(5);
else if (keyboard.digit6Key.wasPressedThisFrame || keyboard.numpad6Key.wasPressedThisFrame) OnNumberPressed(6);
else if (keyboard.digit7Key.wasPressedThisFrame || keyboard.numpad7Key.wasPressedThisFrame) OnNumberPressed(7);
else if (keyboard.digit8Key.wasPressedThisFrame || keyboard.numpad8Key.wasPressedThisFrame) OnNumberPressed(8);
else if (keyboard.digit9Key.wasPressedThisFrame || keyboard.numpad9Key.wasPressedThisFrame) OnNumberPressed(9);
if (keyboard.backspaceKey.wasPressedThisFrame || keyboard.deleteKey.wasPressedThisFrame || keyboard.cKey.wasPressedThisFrame)
{
OnBackspacePressed();
}
if (keyboard.enterKey.wasPressedThisFrame || keyboard.numpadEnterKey.wasPressedThisFrame)
{
OnEnterPressed();
}
}
}
#if ENABLE_LEGACY_INPUT_MANAGER
if (Input.GetKeyDown(KeyCode.Escape))
{
CloseKeypad();
return;
}
#endif
}
public void OpenKeypad()
{
openFrame = Time.frameCount;
if (!gameObject.activeSelf) gameObject.SetActive(true);
if (keypadPanelRoot != null && !keypadPanelRoot.activeSelf)
keypadPanelRoot.SetActive(true);
isOpen = true;
Time.timeScale = 0f;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
enteredCode = "";
UpdateDisplay();
SetStatus("ВВЕДИТЕ 4-ЗНАЧНЫЙ КОД ДОСТУПА", normalStatusColor);
GameAudioSynthesizer.PlayKeypadBeep();
}
public void CloseKeypad()
{
if (!isOpen) return;
isOpen = false;
if (keypadPanelRoot != null)
keypadPanelRoot.SetActive(false);
Time.timeScale = 1f;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
GameAudioSynthesizer.PlayKeypadClear();
}
public void OnNumberPressed(int number)
{
if (isLockedSuccess) return;
if (enteredCode.Length < 4)
{
enteredCode += number.ToString();
GameAudioSynthesizer.PlayKeypadBeep();
UpdateDisplay();
if (enteredCode.Length == 4)
{
SetStatus("НАЖМИТЕ [ВВОД / ENTER] ДЛЯ ПРОВЕРКИ", normalStatusColor);
}
}
}
public void OnBackspacePressed()
{
if (isLockedSuccess) return;
if (enteredCode.Length > 0)
{
enteredCode = enteredCode.Substring(0, enteredCode.Length - 1);
GameAudioSynthesizer.PlayKeypadClear();
UpdateDisplay();
SetStatus("ВВЕДИТЕ 4-ЗНАЧНЫЙ КОД ДОСТУПА", normalStatusColor);
}
}
public void OnClearPressed()
{
if (isLockedSuccess) return;
enteredCode = "";
GameAudioSynthesizer.PlayKeypadClear();
UpdateDisplay();
SetStatus("КОД СБРОШЕН. ВВЕДИТЕ ЗАНОВО", normalStatusColor);
}
public void OnEnterPressed()
{
if (isLockedSuccess) return;
if (enteredCode.Length != 4)
{
SetStatus("ОШИБКА: ТРЕБУЕТСЯ 4 ЦИФРЫ!", errorStatusColor);
GameAudioSynthesizer.PlayErrorCode();
return;
}
if (LevelCodeManager.Instance != null && LevelCodeManager.Instance.ValidateCode(enteredCode))
{
isLockedSuccess = true;
SetStatus("ДОСТУП РАЗРЕШЕН! ЗАПУСК ЛИФТА НА УРОВЕНЬ 2...", successStatusColor);
GameAudioSynthesizer.PlaySuccessChime();
StartCoroutine(RoutineSuccessTransition());
}
else
{
SetStatus("ОТКАЗ В ДОСТУПЕ! НЕВЕРНЫЙ КОД", errorStatusColor);
GameAudioSynthesizer.PlayErrorCode();
StartCoroutine(RoutineWrongCodeShake());
}
}
private IEnumerator RoutineWrongCodeShake()
{
yield return new WaitForSecondsRealtime(0.8f);
enteredCode = "";
UpdateDisplay();
SetStatus("ВВЕДИТЕ 4-ЗНАЧНЫЙ КОД ДОСТУПА", normalStatusColor);
}
private IEnumerator RoutineSuccessTransition()
{
SetStatus("ДОСТУП РАЗРЕШЕН! СПУСК НА УРОВЕНЬ 2...", successStatusColor);
yield return new WaitForSecondsRealtime(1.2f);
if (LevelSuccessUI.Instance != null)
{
LevelSuccessUI.Instance.ShowSuccessScreen();
}
yield return new WaitForSecondsRealtime(1.2f);
Time.timeScale = 1f;
UnityEngine.SceneManagement.SceneManager.LoadScene("Level2");
}
private void UpdateDisplay()
{
for (int i = 0; i < 4; i++)
{
if (digitSlots != null && i < digitSlots.Length && digitSlots[i] != null)
{
if (i < enteredCode.Length)
{
digitSlots[i].text = enteredCode[i].ToString();
digitSlots[i].color = new Color(1.0f, 0.85f, 0.1f, 1.0f);
}
else
{
digitSlots[i].text = "_";
digitSlots[i].color = new Color(0.4f, 0.4f, 0.4f, 0.7f);
}
}
}
}
private void SetStatus(string text, Color color)
{
if (statusText != null)
{
statusText.text = text;
statusText.color = color;
}
}
}