using System; using UnityEngine; using UnityEngine.InputSystem; namespace OnlyScove.Scripts { public class InputReader : MonoBehaviour { [SerializeField] private InputActionAsset inputActions; public InputActionAsset InputActions => inputActions; private const string REBINDS_KEY = "InputRebinds"; private void OnEnable() { if (inputActions != null) { LoadBindings(); inputActions.Enable(); } } private void OnDisable() { if (inputActions != null) { inputActions.Disable(); } } public void SaveBindings() { if (inputActions == null) return; string rebinds = inputActions.SaveBindingOverridesAsJson(); PlayerPrefs.SetString(REBINDS_KEY, rebinds); PlayerPrefs.Save(); } public void LoadBindings() { if (inputActions == null) return; string rebinds = PlayerPrefs.GetString(REBINDS_KEY, string.Empty); if (!string.IsNullOrEmpty(rebinds)) { inputActions.LoadBindingOverridesFromJson(rebinds); } } public void ResetBindings() { if (inputActions == null) return; inputActions.RemoveAllBindingOverrides(); PlayerPrefs.DeleteKey(REBINDS_KEY); PlayerPrefs.Save(); } // Continuous Inputs public virtual Vector2 MoveInput { get; protected set; } public virtual Vector2 LookInput { get; protected set; } public virtual Vector2 ScrollInput { get; protected set; } public virtual bool IsSprintHeld { get; protected set; } public virtual bool IsAttackHeld { get; protected set; } public bool IsAimHeld { get; protected set; } public bool IsBlockHeld { get; protected set; } public bool IsInteractHeld { get; protected set; } public bool IsScopeViewHeld { get; protected set; } public void ApplyNetworkInput(Vector2 move, bool isSprint) { MoveInput = move; IsSprintHeld = isSprint; } // One-shot Events public event Action OnJumpEvent; public event Action OnDodgeEvent; public event Action OnSprintEvent; public event Action OnAttackEvent; public event Action OnCrouchEvent; public event Action OnInteractEvent; public event Action OnNextInteractEvent; public event Action OnPreviousInteractEvent; public event Action OnToggleViewEvent; public event Action OnReloadEvent; public event Action OnStrongAttackEvent; public event Action OnSwitchSideEvent; public event Action OnScopeViewEvent; // UI Events public event Action OnToggleSettingsEvent; // Cho Ctrl+O public event Action OnCancelEvent; // Cho phím ESC hoặc phím đóng UI // Polling flags private bool wasAttackPressed; private bool wasStrongAttackPressed; private bool wasReloadPressed; private bool wasSwitchSidePressed; private bool wasScopeViewPressed; private bool wasInteractPressed; private bool wasDodgePressed; private bool wasCrouchPressed; private bool wasJumpPressed; private bool wasAimReleased; private bool wasNextPressed; private bool wasPreviousPressed; private bool wasToggleViewPressed; public bool ConsumeAttack() { bool v = wasAttackPressed; wasAttackPressed = false; return v; } public bool ConsumeStrongAttack() { bool v = wasStrongAttackPressed; wasStrongAttackPressed = false; return v; } public bool ConsumeReload() { bool v = wasReloadPressed; wasReloadPressed = false; return v; } public bool ConsumeSwitchSide() { bool v = wasSwitchSidePressed; wasSwitchSidePressed = false; return v; } public bool ConsumeScopeView() { bool v = wasScopeViewPressed; wasScopeViewPressed = false; return v; } public bool ConsumeInteract() { bool v = wasInteractPressed; wasInteractPressed = false; return v; } public bool ConsumeDodge() { bool v = wasDodgePressed; wasDodgePressed = false; return v; } public bool ConsumeCrouch() { bool v = wasCrouchPressed; wasCrouchPressed = false; return v; } public bool ConsumeJump() { bool v = wasJumpPressed; wasJumpPressed = false; return v; } public bool ConsumeAimReleased() { bool v = wasAimReleased; wasAimReleased = false; return v; } public bool ConsumeNext() { bool v = wasNextPressed; wasNextPressed = false; return v; } public bool ConsumePrevious() { bool v = wasPreviousPressed; wasPreviousPressed = false; return v; } public bool ConsumeToggleView() { bool v = wasToggleViewPressed; wasToggleViewPressed = false; return v; } public void OnAttack(InputAction.CallbackContext context) { if (context.performed) { wasAttackPressed = true; OnAttackEvent?.Invoke(); IsAttackHeld = true; } if (context.canceled) { IsAttackHeld = false; } } public void OnMove(InputAction.CallbackContext context) { MoveInput = context.ReadValue(); } public void OnLook(InputAction.CallbackContext context) { LookInput = context.ReadValue(); } public void OnScroll(InputAction.CallbackContext context) { ScrollInput = context.ReadValue(); } public void OnSprint(InputAction.CallbackContext context) { if (context.performed) { IsSprintHeld = true; OnSprintEvent?.Invoke(); } if (context.canceled) IsSprintHeld = false; } public void OnToggleView(InputAction.CallbackContext context) { if (context.performed) { Debug.Log("[InputReader] ToggleView Action Performed!"); wasToggleViewPressed = true; OnToggleViewEvent?.Invoke(); } } public void OnJump(InputAction.CallbackContext context) { if (context.performed) { wasJumpPressed = true; OnJumpEvent?.Invoke(); } } public bool ConsumeJumpInput() { bool val = wasJumpPressed; wasJumpPressed = false; return val; } public void OnDodgeOrThrust(InputAction.CallbackContext context) { if (context.performed) { wasDodgePressed = true; OnDodgeEvent?.Invoke(); } } public void OnCrouch(InputAction.CallbackContext context) { if (context.performed) { wasCrouchPressed = true; OnCrouchEvent?.Invoke(); } } public void OnInteract(InputAction.CallbackContext context) { if (context.performed) { wasInteractPressed = true; IsInteractHeld = true; OnInteractEvent?.Invoke(); } if (context.canceled) { IsInteractHeld = false; } } public void OnNext(InputAction.CallbackContext context) { if (context.performed) { wasNextPressed = true; OnNextInteractEvent?.Invoke(); } } public void OnPrevious(InputAction.CallbackContext context) { if (context.performed) { wasPreviousPressed = true; OnPreviousInteractEvent?.Invoke(); } } // UI Callbacks public void OnToggleSettings(InputAction.CallbackContext context) { if (context.performed) { Debug.Log("[InputReader] Toggle Settings Action Performed!"); OnToggleSettingsEvent?.Invoke(); } } public void OnCancel(InputAction.CallbackContext context) { if (context.performed) { Debug.Log("[InputReader] Cancel Action Performed (ESC)!"); OnCancelEvent?.Invoke(); } } public void OnAim(InputAction.CallbackContext context) { if (context.performed) IsAimHeld = true; if (context.canceled) { IsAimHeld = false; wasAimReleased = true; } } public void OnBlock(InputAction.CallbackContext context) { if (context.performed) IsBlockHeld = true; if (context.canceled) IsBlockHeld = false; } public void OnStrongAttack(InputAction.CallbackContext context) { if (context.performed) { wasStrongAttackPressed = true; OnStrongAttackEvent?.Invoke(); } } public void OnReload(InputAction.CallbackContext context) { if (context.performed) { wasReloadPressed = true; OnReloadEvent?.Invoke(); } } public void OnSwitchSide(InputAction.CallbackContext context) { if (context.performed) { wasSwitchSidePressed = true; OnSwitchSideEvent?.Invoke(); } } public void OnScopeView(InputAction.CallbackContext context) { if (context.performed) { wasScopeViewPressed = true; IsScopeViewHeld = true; OnScopeViewEvent?.Invoke(); } if (context.canceled) { IsScopeViewHeld = false; } } } }