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
}