150 lines
7.2 KiB
C#
150 lines
7.2 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using BaseGames.Core.Events;
|
|
|
|
namespace BaseGames.Input
|
|
{
|
|
[CreateAssetMenu(menuName = "Input/InputReader")]
|
|
public class InputReaderSO : ScriptableObject
|
|
{
|
|
[SerializeField] private InputActionAsset _inputActions;
|
|
[SerializeField] private VoidEventChannelSO _onPauseRequested;
|
|
|
|
// ── Gameplay Events ───────────────────────────────────────────────────
|
|
public event Action<Vector2> MoveEvent;
|
|
public event Action JumpStartedEvent;
|
|
public event Action JumpCancelledEvent;
|
|
public event Action AttackEvent;
|
|
public event Action DownAttackEvent;
|
|
public event Action UpAttackEvent;
|
|
public event Action ParryEvent;
|
|
public event Action DashEvent;
|
|
public event Action UseSpringEvent;
|
|
public event Action SwitchSkyFormEvent;
|
|
public event Action SwitchEarthFormEvent;
|
|
public event Action SwitchDeathFormEvent;
|
|
public event Action SoulSkillEvent;
|
|
public event Action SpiritSkill1StartedEvent;
|
|
public event Action SpiritSkill1CancelledEvent;
|
|
public event Action SpiritSkill2StartedEvent;
|
|
public event Action SpiritSkill2CancelledEvent;
|
|
public event Action InteractEvent;
|
|
|
|
// ── UI Events ─────────────────────────────────────────────────────────
|
|
public event Action PauseEvent;
|
|
public event Action<Vector2> NavigateEvent;
|
|
public event Action SubmitEvent;
|
|
public event Action CancelEvent;
|
|
public event Action<Vector2> PointEvent;
|
|
|
|
// ── Polling ───────────────────────────────────────────────────────────
|
|
public Vector2 MoveInput { get; private set; }
|
|
|
|
// ── Runtime state ─────────────────────────────────────────────────────
|
|
private InputActionMap _gameplay;
|
|
private InputActionMap _ui;
|
|
private bool _isBound;
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (_inputActions == null) return;
|
|
_gameplay = _inputActions.FindActionMap("Gameplay", throwIfNotFound: false);
|
|
_ui = _inputActions.FindActionMap("UI", throwIfNotFound: false);
|
|
BindActions();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_gameplay?.Disable();
|
|
_ui?.Disable();
|
|
_isBound = false;
|
|
}
|
|
|
|
// ── Action Map Switching ──────────────────────────────────────────────
|
|
public void EnableGameplayInput() { _ui?.Disable(); _gameplay?.Enable(); }
|
|
public void EnableUIInput() { _gameplay?.Disable(); _ui?.Enable(); }
|
|
public void DisableAllInput() { _gameplay?.Disable(); _ui?.Disable(); }
|
|
|
|
// ── Binding ───────────────────────────────────────────────────────────
|
|
private void BindActions()
|
|
{
|
|
if (_gameplay == null || _isBound) return;
|
|
|
|
BindPerformed(_gameplay, "Move", ctx =>
|
|
{
|
|
MoveInput = ctx.ReadValue<Vector2>();
|
|
MoveEvent?.Invoke(MoveInput);
|
|
});
|
|
BindCanceled(_gameplay, "Move", _ =>
|
|
{
|
|
MoveInput = Vector2.zero;
|
|
MoveEvent?.Invoke(Vector2.zero);
|
|
});
|
|
|
|
BindStarted(_gameplay, "Jump", () => JumpStartedEvent?.Invoke());
|
|
BindCanceled(_gameplay, "Jump", () => JumpCancelledEvent?.Invoke());
|
|
BindStarted(_gameplay, "Attack", () => AttackEvent?.Invoke());
|
|
BindStarted(_gameplay, "DownAttack", () => DownAttackEvent?.Invoke());
|
|
BindStarted(_gameplay, "UpAttack", () => UpAttackEvent?.Invoke());
|
|
BindStarted(_gameplay, "Parry", () => ParryEvent?.Invoke());
|
|
BindStarted(_gameplay, "Dash", () => DashEvent?.Invoke());
|
|
BindStarted(_gameplay, "UseSpring", () => UseSpringEvent?.Invoke());
|
|
BindStarted(_gameplay, "SwitchSkyForm", () => SwitchSkyFormEvent?.Invoke());
|
|
BindStarted(_gameplay, "SwitchEarthForm", () => SwitchEarthFormEvent?.Invoke());
|
|
BindStarted(_gameplay, "SwitchDeathForm", () => SwitchDeathFormEvent?.Invoke());
|
|
BindStarted(_gameplay, "SoulSkill", () => SoulSkillEvent?.Invoke());
|
|
BindStarted(_gameplay, "SpiritSkill1", () => SpiritSkill1StartedEvent?.Invoke());
|
|
BindCanceled(_gameplay, "SpiritSkill1", () => SpiritSkill1CancelledEvent?.Invoke());
|
|
BindStarted(_gameplay, "SpiritSkill2", () => SpiritSkill2StartedEvent?.Invoke());
|
|
BindCanceled(_gameplay, "SpiritSkill2", () => SpiritSkill2CancelledEvent?.Invoke());
|
|
BindStarted(_gameplay, "Interact", () => InteractEvent?.Invoke());
|
|
BindStarted(_gameplay, "Pause", HandlePause);
|
|
|
|
if (_ui != null)
|
|
{
|
|
BindPerformed(_ui, "Navigate", ctx => NavigateEvent?.Invoke(ctx.ReadValue<Vector2>()));
|
|
BindCanceled(_ui, "Navigate", _ => NavigateEvent?.Invoke(Vector2.zero));
|
|
BindStarted(_ui, "Submit", () => SubmitEvent?.Invoke());
|
|
BindStarted(_ui, "Cancel", () => CancelEvent?.Invoke());
|
|
BindStarted(_ui, "Pause", HandlePause);
|
|
BindPerformed(_ui, "Point", ctx => PointEvent?.Invoke(ctx.ReadValue<Vector2>()));
|
|
}
|
|
|
|
_isBound = true;
|
|
}
|
|
|
|
private void HandlePause()
|
|
{
|
|
PauseEvent?.Invoke();
|
|
_onPauseRequested?.Raise();
|
|
}
|
|
|
|
private static void BindStarted(InputActionMap map, string name, Action callback)
|
|
{
|
|
var action = map.FindAction(name, throwIfNotFound: false);
|
|
if (action != null) action.started += _ => callback();
|
|
}
|
|
|
|
private static void BindPerformed(InputActionMap map, string name,
|
|
Action<InputAction.CallbackContext> callback)
|
|
{
|
|
var action = map.FindAction(name, throwIfNotFound: false);
|
|
if (action != null) action.performed += callback;
|
|
}
|
|
|
|
private static void BindCanceled(InputActionMap map, string name,
|
|
Action<InputAction.CallbackContext> callback)
|
|
{
|
|
var action = map.FindAction(name, throwIfNotFound: false);
|
|
if (action != null) action.canceled += callback;
|
|
}
|
|
|
|
private static void BindCanceled(InputActionMap map, string name, Action callback)
|
|
{
|
|
var action = map.FindAction(name, throwIfNotFound: false);
|
|
if (action != null) action.canceled += _ => callback();
|
|
}
|
|
}
|
|
}
|