public class PlayerJump : MonoBehaviour
{
    [SerializeField] private float Jump = 10f;

    [Header("CoyoteTime")]
    [SerializeField] private float _coyoteTimeDuration = 0.15f;
    private float _coyoteTimeCounter;


    private Rigidbody _rb;
    public event Action OnJumped;

    void Awake()
    {
        _rb = GetComponent<Rigidbody>();
    }
    void Update()
    {
        

        if (GroundChecker.Instance.IsGrounded)
        {
            _coyoteTimeCounter = _coyoteTimeDuration;
        }
        else
        {
            _coyoteTimeCounter -= Time.deltaTime;
        }

        if (Input.GetButtonDown("Jump") && _coyoteTimeCounter > 0f)
        {
            JumpLogic();
        }

    }

    private void JumpLogic()
    {

        GroundChecker.Instance.ExitSlopeRay = true;
        _rb.velocity = new Vector3(_rb.velocity.x, 0f, _rb.velocity.z);
        _rb.AddForce(Vector3.up * Jump, ForceMode.Impulse);

        _coyoteTimeCounter = 0f;

        OnJumped?.Invoke();
    }
}


///groundCheck

public bool IsGrounded {  get; private set; }

private void Awake()
{
    Instance = this;
    _rb = GetComponent<Rigidbody>();
}
private void Update()
{
    IsGrounded = Physics.CheckSphere(_spherePos.position, _sphereRadius, _groundLayer);
}

private void FixedUpdate()
{
    if (OnSlope())
    {
        _rb.AddForce(GetSlopeMoveDirection() * PlayerController.Instance.Speed * 2, ForceMode.Force);

        if (_rb.velocity.y > 0)
            _rb.AddForce(Vector3.down * 100, ForceMode.Force);
    }

    if (OnSlope() && !ExitSlopeRay)
    {
        if (_rb.velocity.magnitude > PlayerController.Instance.Speed)
        {
            _rb.velocity = _rb.velocity.normalized * PlayerController.Instance.Speed;
        }
    }
    _rb.useGravity = !OnSlope();
}

private bool CanJump()
{
    return IsGrounded;
}