Make player only jump as long as the button is held?

I am creating a small platformer game for a 4-day contest. I just started, and I am trying new mechanics that I never have before, such as a double jump, wall kick, sprint, and dash. I’m not all that new to Unity, but I haven’t really dove that deep into what’s possible.

So here is my problem. One of my mechanics is when you jump, it will only jump as much as you hold, and then stop jumping. It will have a cap, which is JumpSpeed for the second jump. Note that I only want this on the first jump, as if I put it on the second one it will be really weird.

Here’s my code:

``````if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space))
{
Collider2D[] checkGround = Physics2D.OverlapCircleAll(groundCheck.transform.position, 0.05f);
foreach (Collider2D foundCol in checkGround)
{
if (foundCol.gameObject.CompareTag("Ground"))
{
jumps = maxJumps;
}
}
if (jumps > 0)
{
if (jumps == 2)
{
float jumpLeft = jumpSpeed;
rig.velocity = new Vector2(rig.velocity.x, 0);
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.Space))
{
rig.velocity = new Vector2(rig.velocity.x, rig.velocity.y + 0.1f);
jumpLeft -= 0.1f;
}
if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.Space) || jumpLeft <= 0)
{
jumps--;
}
}
if (jumps == 1)
{
if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space))
{
rig.velocity = new Vector2(rig.velocity.x, jumpSpeed);
jumps--;
}
}
}
}
``````

The second jump works fine; (i have a way to test that) however it’s just this first one. It doesn’t get off the ground at all. If anyone could help, this would be greatly appreciated.

Also, as I stated before, this is due in 4 days, and so I need to finish it ASAP.

There seem to be several issues with your code (I assume the code is inside the Update() function).

The very first if statement will make sure that your code is only executed once, in the frame that the jump key is initially pressed.

``````if (Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space))
``````

Even if the player holds the key, this if statement will not be true again. That is most likely why your player never leaves the ground visibly.

Then in this line

``````   rig.velocity = new Vector2(rig.velocity.x, rig.velocity.y + 0.1f);
``````

you are modifying the velocity by adding 0.1f to it - however, you’re setting y velocity to 0 three lines above it. The velocity will never grow, at best it will be 0.1f.
My suggestion is to move this line

``````rig.velocity = new Vector2(rig.velocity.x, 0);
``````

into an else clause below your if statement.

The other issue is with this line:

``````jumpLeft -= 0.1f;
``````

This is not frame rate independent. This value might or might work depending on how fast your game is running, but it is possible that your jump is over within less of a half second and you will never see the jump. It would be safer to multiply by Time.deltaTime and be frame rate independent.

``````if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.Space))
{
float perSecondDeterioration = 0.1f  * Time.deltaTime;
rig.velocity = new Vector2(rig.velocity.x, rig.velocity.y + perSecondDeterioration );
jumpLeft -= perSecondDeterioration;
}
else
{
rig.velocity = new Vector2(rig.velocity.x, 0);
}
``````