Adding Coyote Time and Jumpbuffer gave player infinite jumps.
I followed a Youtube Tutorial on how to make Coyote jump and also a jumpBuffer using the same method. But the problem is that the player can now jump in air, and I really do not understand how this is even possible. So i don't know how to fix this. I thought of implementing a InputBuffer using Queue, but I think that is just overkill for only one input. So would rather find some kind of solution instead of trying something completely different.
[Header("Player Accesiblility")]
public float hangTime = 1.5f;
private float hangCounter;
public float jumpBufferLength = 0.1f;
private float jumpBufferCount;
void Update()
{
if (coll.onGround) //Coyote Time for Jump
{
hangCounter = hangTime;
}
else
{
hangCounter -= Time.deltaTime;
}
//Jump Buffer
if (Input.GetButtonDown("Jump"))
{
jumpBufferCount = jumpBufferLength;
}
else
{
jumpBufferCount -= Time.deltaTime;
}
if (jumpBufferCount >= 0 && hangCounter > 0f) //Jump Function
{
anim.SetTrigger("jump");
Debug.Log("Jump");
dustParticle.Play();
Jump(Vector2.up, false);
jumpBufferCount = 0;
if (coll.onWall && !coll.onGround)
{
WallJump();
}
}
coll.onGround is from another script, where I just used OverLapCircle.
onGround = Physics2D.OverlapCircle((Vector2)transform.position + bottomOffset, collisionRadius, groundLayer);
Try prevent coyote jump as soon as you jump and only activate it when you're grounded again.
Thanks for the tip, but i'm not sure how to do that. I already made a if statement that only allowed the Coyote Time count when the player is onGround. I'm not sure how I would add another condition that doesn't ruin the Jump Buffer. I have tried different methods now, but everytime I add new condition the other stops working.
Answer by MSavioti · Dec 31, 2020 at 08:47 PM
I'll write a little draft of how I'd do it and hope it'll be of use to you.
private bool _isGrounded;
private bool _canCoyoteJump;
private float _coyoteTime;
private float _coyoteTimeDuration;
private bool CanCoyoteJump => _canCoyoteJump && _coyoteTime < _coyoteTimeDuration;
private void AttemptJumping()
{
if (_isGrounded)
{
Jump();
}
else
{
if (!CanCoyoteJump)
{
BufferJumpInput();
return;
}
else
{
StopCoyoteTimer();
Jump();
}
}
}
private void Jump()
{
// Jump logic
}
// Insert this in FixedUpdate
private void CheckGround()
{
// Raycasting downwards to look for ground
bool foundGround;
if (foundGround)
{
// If found ground but was not grounded, we just landed
if (!_isGrounded)
{
UseJumpBuffer();
}
_isGrounded = true;
}
else
{
// Didn't find ground now, but was grounded in the last check
// means we just left ground
if (_isGrounded)
{
StartCoyoteTimer();
}
_isGrounded = false;
}
}
private void UseJumpBuffer()
{
// If there's a jump input in the buffer, make the char jump
}
private void BufferJumpInput()
{
// Insert input in the buffer if there isn't
}
private void StartCoyoteTimer()
{
// Enable coyote jump and start the timer
}
private void StopCoyoteTimer()
{
// Disable coyote jump and prevent further jumps
}
Cheers.
Thanks it looks really good, but I have no idea how to implement this method. I tried but I somehow F'ed it up, so the player can't even jump anymore.
if (Input.GetButtonDown("Jump")) //Jump Function
{
anim.SetTrigger("jump");
AttemptJumping();
if (coll.onWall && !coll.onGround)
{
WallJump();
}
}
private void AttemptJumping()
{
if (coll.onGround)
{
Jump(Vector2.up, false);
}
else
{
if (!CanCoyoteJump)
{
BufferJumpInput();
return;
}
else
{
StopCoyoteTimer();
Jump(Vector2.up, false);
}
}
}
private void CheckGround()
{
if (coll.foundGround)
{
// If found ground but was not grounded, we just landed
if (!coll.onGround)
{
UseJumpBuffer();
}
_isGrounded = true;
}
else
{
// Didn't find ground now, but was grounded in the last check
// means we just left ground
if (_isGrounded)
{
StartCoyoteTimer();
}
_isGrounded = false;
}
}
private void UseJumpBuffer()
{
// If there's a jump input in the buffer, make the char jump
if (jumpBufferloaded == true)
{
Jump(Vector2.up, false);
}
}
private void BufferJumpInput()
{
// Insert input in the buffer if there isn't
if (jumpBufferloaded == false)
{
jumpBufferloaded = true;
}
}
private void StartCoyoteTimer()
{
// Enable coyote jump and start the timer
_canCoyoteJump = true;
_coyoteTime -= Time.deltaTime;
}
private void StopCoyoteTimer()
{
// Disable coyote jump and prevent further jumps
_canCoyoteJump = false;
_coyoteTime = 0;
}
And what is the purpose of making Void CheckGround, if its not use as an reference?
And what is the purpose of making Void CheckGround, if its not use as an reference?
I do that so I can detect landing and taking off inside the method, but it isn't something mandatory, you can return if a ground was detected and do the rest outside of it.
I'm on the process of uploading my playing controller to my github, but it may take a while to happen. I can come back to this question and post the link when it's playable, but you'd have to wait for it.
That's very kind of you But thank you for the help, meanwhile I will improve this method.
Your answer
Follow this Question
Related Questions
How can make it so only 1 object of type “Ability” can be selected at once? 0 Answers
How to make an enemy 2d chasing player? 1 Answer
Stop Point objects respawning when reloading level 0 Answers
How to detect if ObjectA is looking at ObjectB, and vice versa? 2 Answers
"Object reference not set to the instance of an object" 0 Answers