using System.Collections.Generic; using UnityEngine; public class In : MonoBehaviour { [Header("Выбор источника управления")] static InputSource source; public void Initialize() { #if UNITY_EDITOR source = ComWrapper.IsPortOpen ? new COMinput() : new KeyboardInput(); #else source = new COMinput(); #endif var success = source.Initialize(); if (!success) Debug.LogWarning("Не удалось проинициалзировать источник управления."); } /// Возвращает горизонтальную и вертикальную оси выбранного джойстика. public static Vector2Int GetAxis(JoystickSide side, InteractMode interactMode = InteractMode.Discrete) => new( GetHorizontalAxis(side, interactMode), GetVerticalAxis(side, interactMode)); public static int GetHorizontalAxis( JoystickSide side, InteractMode interactMode = InteractMode.Discrete) { if (side == JoystickSide.Both) { return ToAxis( IsEitherActive(InSignal.left1, InSignal.left2, interactMode), IsEitherActive(InSignal.right1, InSignal.right2, interactMode)); } bool isLeft = side == JoystickSide.Left; InSignal left = isLeft ? InSignal.left1 : InSignal.left2; InSignal right = isLeft ? InSignal.right1 : InSignal.right2; return ToAxis(IsActive(left, interactMode), IsActive(right, interactMode)); } public static int GetVerticalAxis( JoystickSide side, InteractMode interactMode = InteractMode.Discrete) { if (side == JoystickSide.Both) { return ToAxis( IsEitherActive(InSignal.down1, InSignal.down2, interactMode), IsEitherActive(InSignal.up1, InSignal.up2, interactMode)); } bool isLeft = side == JoystickSide.Left; InSignal down = isLeft ? InSignal.down1 : InSignal.down2; InSignal up = isLeft ? InSignal.up1 : InSignal.up2; return ToAxis(IsActive(down, interactMode), IsActive(up, interactMode)); } /// Возвращает состояние кнопки Action выбранного джойстика. public static bool GetAction(JoystickSide side, InteractMode interactMode = InteractMode.Discrete) { if (side == JoystickSide.Both) return IsEitherActive(InSignal.action1, InSignal.action2, interactMode); InSignal action = side == JoystickSide.Left ? InSignal.action1 : InSignal.action2; return IsActive(action, interactMode); } /// Возвращает текущее состояние сервисной кнопки без обработки Up/Down. public static bool GetService() => GetButton(InSignal.service); public static bool GetButton(InSignal button) => source.GetButton(button); public static bool GetButtonDown(InSignal button) => source.GetButtonDown(button); public static bool GetButtonDown(IEnumerable signals) { foreach (var signal in signals) if (GetButtonDown(signal)) return true; return false; } public static bool AnyButton() => source.AnyButton(); private static bool IsActive(InSignal signal, InteractMode interactMode) => interactMode == InteractMode.Discrete ? GetButtonDown(signal) : GetButton(signal); private static bool IsEitherActive( InSignal first, InSignal second, InteractMode interactMode) { bool firstActive = IsActive(first, interactMode); bool secondActive = IsActive(second, interactMode); return firstActive || secondActive; } private static int ToAxis(bool negative, bool positive) => (positive ? 1 : 0) - (negative ? 1 : 0); } public enum Axis { Horizontal, Vertical } public enum JoystickSide { Left, Right, Both } public enum InteractMode { Discrete, Continious }