Kursach_StealthAction/Assets/Scripts/ElevatorKeypadUI.cs
2026-10-23 15:44:09 +03:00

303 lines
9.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
/// <summary>
/// Терминал лифта: ввод 4-значного кода доступа для перехода на 2-й уровень.
/// </summary>
public class ElevatorKeypadUI : MonoBehaviour
{
private static ElevatorKeypadUI _instance;
public static ElevatorKeypadUI Instance
{
get
{
if (_instance == null)
{
_instance = Object.FindAnyObjectByType<ElevatorKeypadUI>(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;
}
}
}