using UnityEngine; /// /// Статический фасад для унифицированного доступа к системе ввода. /// Предоставляет глобальный интерфейс для работы с управлением независимо от выбранного источника. /// /// /// Этот класс является точкой входа для всей игровой логики, работающей с вводом. /// Автоматически инициализирует выбранный источник управления (клавиатура или COM-порт) /// и предоставляет статические методы для удобного доступа из любого места кода. /// /// Использование: /// 1. Настройте тип ввода в инспекторе /// 2. Вызовите Initialize() при старте игры /// 3. Используйте статические методы для проверки ввода /// public class In : MonoBehaviour { [Header("Выбор источника управления")] [SerializeField] private InputSourceType inputType; /// Возвращает true, если выбран COM-режим (нужны физические платы) public bool UsesCOM => inputType == InputSourceType.COM; static InputSource source; // вспомогательный экземпляр клавиатурного источника для локальной проверки (фолбэк при COM) static KeyboardInput keyboardOverride; public static System.Action ButtonEvent; // на неё подписываемся в GameMenager обновляем таймер /// /// Инициализирует систему ввода на основе выбранного типа. /// Должен быть вызван один раз при запуске приложения. /// /// /// Создает соответствующий экземпляр InputSource: /// - KeyboardInput для тестирования на клавиатуре /// - COMinput для работы с периферийной платой /// public void Initialize() { source = inputType switch { InputSourceType.Keyboard => new KeyboardInput(), InputSourceType.COM => new COMinput(), _ => throw new System.NotImplementedException() }; var success = source.Initialize(); if (!success) Debug.LogWarning("Не удалось проинициалзировать источник управления."); } // ================================================================================ // СТАТИЧЕСКИЕ МЕТОДЫ ДЛЯ РАБОТЫ С ФИЗИЧЕСКИМИ ПИНАМИ // ================================================================================ /// Проверяет состояние конкретной кнопки по её физическому пину public static bool GetButton(ButtonPinMapping button) => source.GetButton(button); /// Проверяет нажатие кнопки по пину в текущем кадре public static bool GetButtonDown(ButtonPinMapping button) { bool result = source.GetButtonDown(button); if(result) ButtonEvent?.Invoke(); else if (source is COMinput) { // для режима COM позволяем секретную кнопку также срабатывать с клавиатуры if (button == ButtonPinMapping.secret1 || button == ButtonPinMapping.secret2) { if (keyboardOverride == null) { keyboardOverride = new KeyboardInput(); try { keyboardOverride.Initialize(); } catch { /* ignore */ } } try { if (keyboardOverride != null && keyboardOverride.GetButtonDown(button)) { ButtonEvent?.Invoke(); return true; } } catch { /* ignore potential errors from KeyboardInput */ } } } return result; } /// Проверяет отпускание кнопки по пину в текущем кадре public static bool GetButtonUp(ButtonPinMapping button) => source.GetButtonUp(button); /// Проверяет состояние кнопки по числовому индексу пина public static bool GetButton(int pinindex) => source.GetButton(pinindex); /// Проверяет нажатие кнопки по индексу пина в текущем кадре public static bool GetButtonDown(int pinindex) => source.GetButtonDown(pinindex); /// Проверяет отпускание кнопки по индексу пина в текущем кадре public static bool GetButtonUp(int pinindex) => source != null && source.GetButtonUp(pinindex); // ================================================================================ // СТАТИЧЕСКИЕ МЕТОДЫ ДЛЯ РАБОТЫ С АБСТРАКТНЫМИ ДЕЙСТВИЯМИ ИГРОКОВ // ================================================================================ /// Проверяет состояние действия для любого из игроков public static bool GetButtonAnyPlayer(PlayerAction button) => source != null && source.GetButtonAnyPlayer(button); /// Проверяет начало действия любым игроком в текущем кадре public static bool GetButtonDownAnyPlayer(PlayerAction button) => source != null && source.GetButtonDownAnyPlayer(button); /// Проверяет завершение действия любым игроком в текущем кадре public static bool GetButtonUpAnyPlayer(PlayerAction button) => source != null && source.GetButtonUpAnyPlayer(button); /// Проверяет состояние действия для текущего активного игрока public static bool GetButtonCurrentPlayer(PlayerAction button) => source != null && source.GetButtonCurrentPlayer(button); /// Проверяет начало действия текущим игроком в текущем кадре public static bool GetButtonDownCurrentPlayer(PlayerAction button) => source != null && source.GetButtonDownCurrentPlayer(button); /// Проверяет завершение действия текущим игроком в текущем кадре public static bool GetButtonUpCurrentPlayer(PlayerAction button) => source != null && source.GetButtonUpCurrentPlayer(button); }