using UnityEngine; using UnityEngine.InputSystem; public class HeavyBall : MonoBehaviour { [Header("References")] [SerializeField] private PlayerInputManager playerInputManager; [SerializeField] private Rigidbody rb; [SerializeField] private Camera mainCamera; [Space] [Header("Player Parameters")] [SerializeField, Range(0f, 100f)] private float moveSpeed; [SerializeField, Range(0f, 100f)] private float airSpeed; [Space] [Header("Jump Parameters")] [SerializeField, Range(0f, 100f)] private float jumpMultiplier; [SerializeField, Range(0f, 100f)] private float holdThreshold; [Space] [Header("Grounded Settings")] [SerializeField] private LayerMask groundLayer; [SerializeField] private LayerMask grabbableLayer; [SerializeField, Range(0f, 100f)] private float radius; [SerializeField, Range(0f, 100f)] private float maxDistance; [SerializeField, Range(0f, 100f)] private float groundDamping; [SerializeField, Range(0f, 100f)] private float airDamping; [Space] [Header("Custom Gravity Parameters")] [SerializeField, Range(0f, 100f)] private float playerGravity; [SerializeField, Range(0f, 100f)] private float groundMultiplier; [SerializeField, Range(0f, 100f)] private float upwardMultiplier; [SerializeField, Range(0f, 100f)] private float downwardMultiplier; [Space] [Header("Bool Parameters")] [SerializeField] private bool isMoving; [SerializeField] private bool isGrounded; private float jumpHoldTime = 0f; Vector2 currentInput; Vector3 moveDirection; RaycastHit hit; private void Start() { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } private void Update() { HandleInput(); HandleJump(); } private void FixedUpdate() { HandleMovement(); HandleGroundCheck(); HandleCustomGravity(); } private void HandleMovement() { Vector2 input = Vector2.ClampMagnitude(currentInput, 1f); Vector3 camForward = mainCamera.transform.forward; Vector3 camRight = mainCamera.transform.right; camForward.y = 0f; camRight.y = 0f; camForward.Normalize(); camRight.Normalize(); moveDirection = camForward * input.y + camRight * input.x; moveDirection = moveDirection.normalized; float currentSpeed = isGrounded ? moveSpeed : airSpeed; rb.AddForce(moveDirection * currentSpeed, ForceMode.Force); } private void HandleJump() { if (playerInputManager.jumpAction.action.IsPressed() && isGrounded) { jumpHoldTime += Time.deltaTime; } else { if (jumpHoldTime > 0f) { float finalJump; if (jumpHoldTime >= holdThreshold) finalJump = 1.1f; else finalJump = 0.8f; rb.AddForce(new(0, finalJump * jumpMultiplier, 0), ForceMode.Impulse); jumpHoldTime = 0f; } } } private void HandleGroundCheck() { isGrounded = (Physics.SphereCast(transform.position, radius, Vector3.down, out hit, maxDistance, groundLayer)); if (isGrounded) { rb.linearDamping = groundDamping; } else { rb.linearDamping = airDamping; } } private void HandleCustomGravity() { if (isGrounded) { rb.AddForce(Physics.gravity * groundMultiplier, ForceMode.Acceleration); } else { if (rb.linearVelocity.y > 0f) { rb.AddForce(Physics.gravity * upwardMultiplier, ForceMode.Acceleration); } else if (rb.linearVelocity.y < 0f) { rb.AddForce(Physics.gravity * downwardMultiplier, ForceMode.Acceleration); } } } private void HandleInput() { currentInput = playerInputManager.moveAction.action.ReadValue<Vector2>(); isMoving = currentInput.sqrMagnitude > 0.01f; } }