357 lines
10 KiB
C#
357 lines
10 KiB
C#
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using System.Collections;
|
|
|
|
/// <summary>
|
|
/// Modular input handler that replaces PlayerScript.
|
|
/// Handles player input routing to character systems.
|
|
/// Only active when character is player-controlled.
|
|
/// </summary>
|
|
[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<Animator>();
|
|
characterMovement = GetComponent<CharacterMovement>();
|
|
characterAttacks = GetComponent<CharacterAttacks>();
|
|
animationManager = GetComponent<AnimationManager>();
|
|
inputToAnimation = GetComponent<InputToAnimation>();
|
|
teamMember = GetComponent<TeamMember>();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Input System Callbacks
|
|
|
|
/// <summary>
|
|
/// Called by Input System for movement input (joystick/WASD)
|
|
/// </summary>
|
|
public void OnMove(InputAction.CallbackContext context)
|
|
{
|
|
if (!enabled) return;
|
|
|
|
input = context.ReadValue<Vector2>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Mobile-specific movement handler
|
|
/// </summary>
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by Input System for jump input
|
|
/// </summary>
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle punch/jab attacks - routed through InputToAnimation
|
|
/// </summary>
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Toggle pause menu
|
|
/// </summary>
|
|
public void OnTogglePause(InputAction.CallbackContext context)
|
|
{
|
|
if (!context.performed) return;
|
|
|
|
PlayerManagerNew playerManager = FindFirstObjectByType<PlayerManagerNew>();
|
|
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
|
|
|
|
/// <summary>
|
|
/// Set player input active/inactive
|
|
/// </summary>
|
|
public void SetPlayerInputActive(bool active)
|
|
{
|
|
PlayerInput playerInput = GetComponent<PlayerInput>();
|
|
if (playerInput != null)
|
|
{
|
|
playerInput.enabled = active;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the current input direction relative to camera
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the camera reference
|
|
/// </summary>
|
|
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
|
|
}
|