using UnityEngine; using UnityEngine.InputSystem; public class PlayerMovement : MonoBehaviour { [Header("Control Mode")] [Tooltip("Is this player controlled by human input or AI?")] public bool isPlayerControlled = false; [Header("Movement Settings")] public float moveSpeed = 5f; public float rotationSpeed = 10f; public float maxSpeed = 8f; public float acceleration = 15f; public float deceleration = 10f; private Vector2 moveInput; private PlayerInput playerInput; private Rigidbody rb; private PlayerAIMovement aiMovement; private PlayerController playerController; void Awake() { playerInput = GetComponent(); aiMovement = GetComponent(); playerController = GetComponent(); } void Start() { rb = GetComponent(); // Configure Rigidbody for hockey physics if (rb != null) { rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezePositionY; rb.linearDamping = 1f; } // Enable/disable AI based on control mode if (aiMovement != null) { aiMovement.IsAIControlled = !isPlayerControlled; } // Disable player input if AI controlled if (playerInput != null) { playerInput.enabled = isPlayerControlled; } } public void OnMove(InputAction.CallbackContext context) { if (!isPlayerControlled) return; moveInput = context.ReadValue(); } void FixedUpdate() { if (isPlayerControlled) { HandlePlayerMovement(); } // AI movement is handled by PlayerAIMovement component } void HandlePlayerMovement() { if (rb == null) return; // Don't allow movement if frozen (during faceoff) if (playerController != null && playerController.IsFrozen()) { // Immediately stop all movement when frozen rb.linearVelocity = Vector3.zero; rb.angularVelocity = Vector3.zero; return; } // Don't allow movement if puck is not in play if (GameManager.Instance != null && !GameManager.Instance.IsPuckInPlay) { // Apply deceleration when puck is not in play if (rb.linearVelocity.magnitude > 0.1f) { Vector3 decelerationForce = -rb.linearVelocity.normalized * deceleration; rb.AddForce(decelerationForce, ForceMode.Acceleration); } else { rb.linearVelocity = Vector3.zero; } return; } if (moveInput.magnitude > 0.1f) { // Use force-based movement for realistic hockey physics Vector3 inputDirection = new Vector3(moveInput.x, 0, moveInput.y).normalized; Vector3 desiredVelocity = inputDirection * moveSpeed; Vector3 velocityDifference = desiredVelocity - rb.linearVelocity; // Apply acceleration force rb.AddForce(velocityDifference * acceleration, ForceMode.Acceleration); // Clamp velocity to max speed if (rb.linearVelocity.magnitude > maxSpeed) { rb.linearVelocity = rb.linearVelocity.normalized * maxSpeed; } // Rotate toward movement direction Vector3 lookDirection = new Vector3(moveInput.x, 0, moveInput.y); if (lookDirection != Vector3.zero) { Quaternion targetRotation = Quaternion.LookRotation(lookDirection); transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.fixedDeltaTime); } } else { // Apply deceleration when no input if (rb.linearVelocity.magnitude > 0.1f) { Vector3 decelerationForce = -rb.linearVelocity.normalized * deceleration; rb.AddForce(decelerationForce, ForceMode.Acceleration); } else { rb.linearVelocity = Vector3.zero; } } } /// /// Switch between player and AI control /// public void SetControlMode(bool playerControlled) { isPlayerControlled = playerControlled; if (aiMovement != null) { aiMovement.IsAIControlled = !playerControlled; } if (playerInput != null) { playerInput.enabled = playerControlled; } } }