using System.Collections; using UnityEngine; using UnityEngine.InputSystem; public class PlayerController : MonoBehaviour { private Rigidbody2D _rigidbody; private Vector2 inputVector; private int maxJumpCount = 2; private int currentJumpCount = 2; private bool isGrounded; [SerializeField] private float moveSpeed = 9f; [SerializeField] private float jumpSpeed = 18.2f; [SerializeField] private float jumpCutMultiplier = 0.3f; [SerializeField] private float minJumpDuration = 0.1f; private float _jumpStartTime; private void Start() { _rigidbody = gameObject.GetComponent(); } private void FixedUpdate() { isGrounded = Physics2D.Raycast(transform.position, Vector2.down, 1.25f, LayerMask.GetMask("Ground")); Debug.DrawRay(transform.position, Vector2.down * 1.25f, Color.red); if (isGrounded && _rigidbody.linearVelocity.y <= 0.1f) { currentJumpCount = maxJumpCount; } MovePlayer(); } private void OnMove(InputValue value) { Vector2 input = value.Get(); inputVector = new Vector2(input.x * moveSpeed, 0); } private void OnJump(InputValue value) { if (value.isPressed) { if (currentJumpCount > 0) { currentJumpCount--; _jumpStartTime = Time.time; StopAllCoroutines(); _rigidbody.linearVelocity = new Vector2(_rigidbody.linearVelocity.x, 0); _rigidbody.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse); } } else { float timeElapsed = Time.time - _jumpStartTime; if (timeElapsed >= minJumpDuration) { CutJumpVelocity(); } else { float delay = minJumpDuration - timeElapsed; StartCoroutine(DelayedJumpCut(delay)); } } } private void CutJumpVelocity() { if (_rigidbody.linearVelocity.y > 0) { _rigidbody.linearVelocity = new Vector2(_rigidbody.linearVelocity.x, _rigidbody.linearVelocity.y * jumpCutMultiplier); } } private IEnumerator DelayedJumpCut(float delay) { yield return new WaitForSeconds(delay); CutJumpVelocity(); } private void MovePlayer() { _rigidbody.linearVelocity = new Vector2(inputVector.x, _rigidbody.linearVelocity.y); } }