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
}