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 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 NavigateEvent; public event Action SubmitEvent; public event Action CancelEvent; public event Action 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(); 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())); 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())); } _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 callback) { var action = map.FindAction(name, throwIfNotFound: false); if (action != null) action.performed += callback; } private static void BindCanceled(InputActionMap map, string name, Action 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(); } } }