Danro/Assets/Scripts/Controls/ComInputToInputSystemAdapter.cs
Danil Iarosh 2f2d100eae feat(inputs): remove obsolete COM input system and update dependencies
- Removed deprecated ButtonPinMapping enum and related COM input classes- Updated ComInputToInputSystemAdapter with improved binding logic- Refactored GameManager to use new globals prefab path
- Enhanced GameEndUIController with event system focus management
- Modified Globals prefab to use pin-based input bindings
- Cleaned up obsolete COM system wrapper and native wrapper classes
- Adjusted input adapter to support pin bindings over action bindings
- Updated manufacturer name in virtual gamepad description
2025-11-04 17:06:51 +03:00

171 lines
6.5 KiB
C#
Raw 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;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
/// <summary>
/// Мост из твоего фасада In (COM/клава и т.д.) в новый Input System.
/// Создаёт виртуальный Gamepad и обновляет его состояние на основе:
/// - действий игроков (PlayerAction), или
/// - физических пинов (int / ButtonPinMapping)
/// Выбирай способ через списки маппинга в инспекторе.
/// </summary>
[DefaultExecutionOrder(-100)] // пораньше, чтобы UI увидел ввод
public class ComInputToInputSystemAdapter : MonoBehaviour
{
[Header("Источник состояния")]
[Tooltip("Если true — брать состояние из In.GetButton* AnyPlayer; если false — из CurrentPlayer.")]
public bool useAnyPlayer = true;
[Header("Маппинг по действиям (PlayerAction -> Gamepad)")]
public List<ActionBinding> actionBindings = new();
[Header("Маппинг по пинам (индекс пина -> Gamepad)")]
public List<PinBinding> pinBindings = new();
[Header("Отладка")]
public bool logCreateDevice = true;
private static Gamepad _virtualPad;
private GamepadState _state;
// Защита от дублей при отключённом Domain Reload
private static bool _deviceCreated;
[Serializable]
public struct ActionBinding
{
public PlayerAction action; // твой enum
public TargetTarget target;
public GamepadButton button; // если target == Button
public DpadDir dpadDirection; // если target == Dpad
}
[Serializable]
public struct PinBinding
{
public int pinIndex; // твой физический индекс пина
public TargetTarget target;
public GamepadButton button; // если target == Button
public DpadDir dpadDirection; // если target == Dpad
}
public enum TargetTarget { Button, Dpad }
public enum DpadDir { Up, Down, Left, Right }
private void Awake()
{
Initialize();
}
private void OnEnable() => Initialize();
private void Update()
{
if (_virtualPad == null) return;
_state = default;
// 1) По действиям
foreach (ActionBinding b in actionBindings)
{
bool pressed = useAnyPlayer
? In.GetButtonAnyPlayer(b.action)
: In.GetButtonCurrentPlayer(b.action);
ApplyBinding(ref _state, b.target, b.button, b.dpadDirection, pressed);
}
// 2) По пинам
foreach (PinBinding b in pinBindings)
{
bool pressed = In.GetButton(b.pinIndex);
ApplyBinding(ref _state, b.target, b.button, b.dpadDirection, pressed);
}
InputSystem.QueueStateEvent(_virtualPad, _state);
// Обновлять InputSystem вручную не нужно (обновится в цикле Unity)
}
public void Initialize()
{
EnsureVirtualGamepad();
TryAddDefaultBindingsIfEmpty();
}
private static void ApplyBinding(ref GamepadState st, TargetTarget target, GamepadButton btn, DpadDir dir, bool pressed)
{
if (!pressed) return;
if (target == TargetTarget.Button)
{
st = st.WithButton(btn, true);
}
else
{
st = dir switch
{
DpadDir.Up => st.WithButton(GamepadButton.DpadUp, true),
DpadDir.Down => st.WithButton(GamepadButton.DpadDown, true),
DpadDir.Left => st.WithButton(GamepadButton.DpadLeft, true),
DpadDir.Right => st.WithButton(GamepadButton.DpadRight, true),
_ => st
};
}
}
private void EnsureVirtualGamepad()
{
if (_deviceCreated && _virtualPad != null) return;
// ищем уже созданный «COM Bridge», чтобы не дублировать
foreach (var dev in InputSystem.devices)
{
if (dev is not Gamepad { description: { product: "COM Bridge Gamepad" } } gp) continue;
_virtualPad = gp;
_deviceCreated = true;
return;
}
InputDeviceDescription desc = new()
{
interfaceName = "Virtual",
deviceClass = "Gamepad",
product = "COM Bridge Gamepad",
manufacturer = "Robotic Retailers"
};
_virtualPad = (Gamepad)InputSystem.AddDevice(desc);
_deviceCreated = true;
if (logCreateDevice) Debug.Log("[InputBridge] Виртуальный Gamepad создан: " + _virtualPad);
}
private void TryAddDefaultBindingsIfEmpty()
{
// Если пусто — добавим базовый маппинг стрелок на D-Pad.
if (actionBindings.Count != 0) return;
TryAddActionBinding(PlayerAction.up, TargetTarget.Dpad, GamepadButton.North, DpadDir.Up);
TryAddActionBinding(PlayerAction.down, TargetTarget.Dpad, GamepadButton.South, DpadDir.Down);
TryAddActionBinding(PlayerAction.left, TargetTarget.Dpad, GamepadButton.West, DpadDir.Left);
TryAddActionBinding(PlayerAction.right, TargetTarget.Dpad, GamepadButton.East, DpadDir.Right);
TryAddActionBinding(PlayerAction.action, TargetTarget.Button, GamepadButton.South, DpadDir.Up);
TryAddActionBinding(PlayerAction.action, TargetTarget.Button, GamepadButton.East, DpadDir.Up);
// SafeTry(() => actionBindings.Add(new ActionBinding { action = PlayerAction.action, target = TargetTarget.Button, button = GamepadButton.South, dpadDirection = DpadDir.Up }));
// SafeTry(() => actionBindings.Add(new ActionBinding { action = PlayerAction.extra, target = TargetTarget.Button, button = GamepadButton.East, dpadDirection = DpadDir.Up }));
}
private void TryAddActionBinding(PlayerAction action, TargetTarget target, GamepadButton btn, DpadDir dir)
{
SafeTry(() => actionBindings.Add(new ActionBinding { action = action, target = target, button = btn, dpadDirection = dir }));
}
private static void SafeTry(Action a)
{
try { a(); } catch { /* если в твоём enum нет таких значений — просто пропустим */ }
}
}