using UnityEngine; using UnityEngine.InputSystem; using System.Collections; /// /// Modular input handler that replaces PlayerScript. /// Handles player input routing to character systems. /// Only active when character is player-controlled. /// [RequireComponent(typeof(Animator))] public class CharacterInputHandler : MonoBehaviour { [Header("References")] [SerializeField] private CharacterStats characterStats; // Cached components private Animator anim; private CharacterMovement characterMovement; private CharacterAttacks characterAttacks; private AnimationManager animationManager; private InputToAnimation inputToAnimation; private TeamMember teamMember; [Header("State")] [Tooltip("Public input vector for other scripts to read")] public Vector2 input; [Tooltip("Is the character currently blocking")] public bool block; [Tooltip("Is the character currently dodging")] public bool dodge; [Tooltip("Are attacks enabled (permission flag)")] public bool attackEnabled = true; [Tooltip("Is the character in a helpless state")] public bool helpless; [Tooltip("Is the character being held")] public bool held; [Header("Camera")] [SerializeField] private Camera mainCamera; [Header("Block/Dodge Settings")] [SerializeField] private float blockDuration = 0.5f; [SerializeField] private float dodgeDuration = 0.4f; #region Unity Lifecycle private void Awake() { CacheComponents(); } private void Start() { // Initialize camera if not set if (mainCamera == null) { mainCamera = Camera.main; } // Initialize state block = false; dodge = false; helpless = false; held = false; } private void OnEnable() { // When enabled (player takes control), ensure input starts fresh input = Vector2.zero; } private void OnDisable() { // When disabled (AI takes control), clear input input = Vector2.zero; block = false; dodge = false; } private void CacheComponents() { anim = GetComponent(); characterMovement = GetComponent(); characterAttacks = GetComponent(); animationManager = GetComponent(); inputToAnimation = GetComponent(); teamMember = GetComponent(); } #endregion #region Input System Callbacks /// /// Called by Input System for movement input (joystick/WASD) /// public void OnMove(InputAction.CallbackContext context) { if (!enabled) return; input = context.ReadValue(); } /// /// Mobile-specific movement handler /// public void OnMoveMobile() { if (!enabled) return; // Block camera updates only during blocking or dodging if (block || dodge) return; // Input is already filled by OnMove from the Input System // Handle any mobile-specific camera logic here if needed } /// /// Called by Input System for jump input /// public void OnJump(InputAction.CallbackContext context) { if (!enabled || !context.performed) return; if (helpless || held) return; // Note: Jump is handled by CharacterMovement's gravity/grounding system // This callback can be used for additional jump logic if needed } /// /// Handle punch/jab attacks - routed through InputToAnimation /// public void OnPunch(InputAction.CallbackContext context) { // No-op: Handled by InputToAnimation } public void OnKick(InputAction.CallbackContext context) { // No-op: Handled by InputToAnimation } public void OnJab(InputAction.CallbackContext context) { // No-op: Handled by InputToAnimation } public void OnHaymaker(InputAction.CallbackContext context) { // No-op: Handled by InputToAnimation } // Mobile attack handlers public void OnPunchMobileNew(InputAction.CallbackContext context) { // No-op: Handled by InputToAnimation } public void OnKickMobileNew(InputAction.CallbackContext context) { // No-op: Handled by InputToAnimation } /// /// Toggle pause menu /// public void OnTogglePause(InputAction.CallbackContext context) { if (!context.performed) return; PlayerManagerNew playerManager = FindFirstObjectByType(); if (playerManager != null) { // Toggle pause based on current state if (playerManager.pause) { playerManager.Resume(); } else { playerManager.Pause(); } } } #endregion #region Block and Dodge public void StartBlock() { if (block || dodge || helpless || held) return; StartCoroutine(BlockCoroutine()); } public void StartDodge() { if (block || dodge || helpless || held) return; StartCoroutine(DodgeCoroutine()); } private IEnumerator BlockCoroutine() { block = true; if (anim != null) { anim.SetBool("Block", true); } yield return new WaitForSeconds(blockDuration); block = false; if (anim != null) { anim.SetBool("Block", false); } } private IEnumerator DodgeCoroutine() { dodge = true; if (anim != null) { anim.SetTrigger("Dodge"); } yield return new WaitForSeconds(dodgeDuration); dodge = false; } #endregion #region Public Methods /// /// Set player input active/inactive /// public void SetPlayerInputActive(bool active) { PlayerInput playerInput = GetComponent(); if (playerInput != null) { playerInput.enabled = active; } } /// /// Get the current input direction relative to camera /// public Vector3 GetDirectionRelativeToCamera() { if (mainCamera == null) return Vector3.zero; Vector3 cameraForward = mainCamera.transform.forward; Vector3 cameraRight = mainCamera.transform.right; cameraForward.y = 0; cameraRight.y = 0; cameraForward.Normalize(); cameraRight.Normalize(); return (cameraForward * input.y + cameraRight * input.x).normalized; } /// /// Update the camera reference /// public void SetMainCamera(Camera camera) { mainCamera = camera; // Also update CharacterMovement if present if (characterMovement != null) { // CharacterMovement has its own mainCamera field } } #endregion #region Legacy Compatibility (No-ops for Input System routing) // These methods exist for legacy compatibility with PlayerScript // All attack inputs are now routed through InputToAnimation public void OnSpinningBackfist(InputAction.CallbackContext c) { } public void OnElbowSmash(InputAction.CallbackContext c) { } public void OnChargePunch(InputAction.CallbackContext c) { } public void OnAirPunch(InputAction.CallbackContext c) { } public void OnDropKick(InputAction.CallbackContext c) { } public void OnLowKick(InputAction.CallbackContext c) { } public void OnStrike(InputAction.CallbackContext c) { } public void OnLook(InputAction.CallbackContext c) { } public void OnSprint(InputAction.CallbackContext c) { } // Vicious attacks public void OnChokeslam(InputAction.CallbackContext c) { } public void OnSuplex(InputAction.CallbackContext c) { } public void OnGiantSwing(InputAction.CallbackContext c) { } public void OnDiamondCrusher(InputAction.CallbackContext c) { } // Special attacks public void OnRKO(InputAction.CallbackContext c) { } public void OnSpear(InputAction.CallbackContext c) { } public void OnRockBottom(InputAction.CallbackContext c) { } public void OnSumoSlap(InputAction.CallbackContext c) { } public void OnJavelinTackle(InputAction.CallbackContext c) { } public void OnF5(InputAction.CallbackContext c) { } public void OnSwantomBomb(InputAction.CallbackContext c) { } // Mobile vicious/special public void OnViciousAttackMobile(InputAction.CallbackContext c) { } public void OnSpecialAttackMobile(InputAction.CallbackContext c) { } // Punch variations public void OnRight(InputAction.CallbackContext c) { } public void OnLeftHook(InputAction.CallbackContext c) { } public void OnRightHook(InputAction.CallbackContext c) { } public void OnLeftElbow(InputAction.CallbackContext c) { } public void OnRightElbow(InputAction.CallbackContext c) { } public void OnRightBody(InputAction.CallbackContext c) { } public void OnPowerPunchLeft(InputAction.CallbackContext c) { } public void OnSupermanPunch(InputAction.CallbackContext c) { } // Kick variations public void OnLegKickRight(InputAction.CallbackContext c) { } public void OnBodyKickRight(InputAction.CallbackContext c) { } public void OnKneeRight(InputAction.CallbackContext c) { } public void OnBackSideKick(InputAction.CallbackContext c) { } public void OnFrontKickRight(InputAction.CallbackContext c) { } public void OnLegPowerKickRight(InputAction.CallbackContext c) { } // Jump variations public void OnJumpBack(InputAction.CallbackContext c) { } public void OnJumpLeft(InputAction.CallbackContext c) { } public void OnJumpRight(InputAction.CallbackContext c) { } // Block variations public void OnBlockStepBack(InputAction.CallbackContext c) { } public void OnBlockBodyLeft(InputAction.CallbackContext c) { } public void OnBlockLeg(InputAction.CallbackContext c) { } #endregion }