using System; using KBCore.Refs; using UnityEngine; using UnityEngine.InputSystem; namespace Infrastructure.Unity { [RequireComponent(typeof(Rigidbody))] public class PlayerController : MonoBehaviour { [Header("Movement Settings")] [SerializeField] private float moveSpeed = 8f; [SerializeField] private float maxVelocityChange = 10f; [Header("Interaction")] [SerializeField] private LayerMask tileLayer; [SerializeField] private float groundCheckDistance = 1.5f; [Self] [SerializeField] private Rigidbody rb; private InputSystem_Actions _actions; private Vector2 _moveInput; public Rigidbody Rigidbody => rb; private void OnEnable() { _actions.Player.Enable(); _actions.Player.Move.performed += OnMovePerformed; _actions.Player.Move.canceled += OnMoveCanceled; } private void OnDisable() { _actions.Player.Move.performed -= OnMovePerformed; _actions.Player.Move.canceled -= OnMoveCanceled; _actions.Player.Disable(); } private void Awake() { _actions = new InputSystem_Actions(); rb.freezeRotation = true; rb.useGravity = true; } private void FixedUpdate() { HandleMovement(); DetectGround(); } private void HandleMovement() { var targetVelocity = new Vector3(_moveInput.x, 0f, _moveInput.y) * moveSpeed; var velocity = rb.linearVelocity; var velocityChange = (targetVelocity - velocity); velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange); velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange); velocityChange.y = 0f; rb.AddForce(velocityChange, ForceMode.VelocityChange); } private void DetectGround() { if (Physics.Raycast(transform.position, Vector3.down, out var hit, groundCheckDistance, tileLayer)) { if (hit.collider.TryGetComponent(out var tileAdapter)) { tileAdapter.OnPlayerStep(); } } } private void OnMovePerformed(InputAction.CallbackContext ctx) { _moveInput = ctx.ReadValue(); } private void OnMoveCanceled(InputAction.CallbackContext ctx) { _moveInput = Vector2.zero; } } }