Jump on UIButton

Hi!

I’m making a small platformer but have run in to a problem.

For now I have the character set up so he jumps on

if (Input.GetKeyDown("space"))

Then it runs

public void Jump(){
    rb.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, 10), ForceMode2D.Impulse);
    ps.enableEmission = true;
}

I have a small snippet limiting the player from jumping too high but a little bit higher when holding down the Space button.

    if (rb.velocity.y < 0){
        rb.velocity += Vector2.up * Physics2D.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
    } else if (rb.velocity.y > 0 && !Input.GetButton("Jump") && !JumpButtonDown){
        rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
    }

I want to make a onscreen button for jumping. So what I’ve set up a UI Button and made a bool for checking if it’s pressed

    public bool JumpButtonDown;

and a eventlistener on the UI Button Up + Down. Checking if the button is pressed

public void OnPointerDown(PointerEventData eventData) {
_down = true;
}

public void OnPointerUp(PointerEventData eventData) {
_down = false;
}
}

It kinda of sorta works, but the player is not being limited by the button.

With Keydown()
pitifulspecificchanticleer

With UIButton()
miniaturefakebasilisk

It doesnt look like you are checking whether the player is grounded or not. Add in a isGrounded bool or something that makes it so you can only jump when player is on the ground or an allowable object.

Your button handling is strange. In fact, you do not need to read OnPointerUp.

You are working with _down variable as it was bool tracking whether user is currently touching on-screen button. It is true all the time between pointer down and up and if you do not reset it to false in jump processing code, then you are performing many jumps in row (probably every frame while _down is true).

What you need is to work with it like with trigger - just set it once in OnPointerDown. Check in game loop, whether _down is true. If yes, make jump and reset _down to false. Ignore OnPointerUp.

This is base. Other issues may arise from what @Cornysam writes - like checking if grounded to prevent in-air jumps, etc.

1 Like

I am checking on PointerUp is because I want the player to jump a little bit higher when the button is being held. Similar to a “Mario-jump”

If I reset after a jump is being made I will kinda loose that mechanic right?

Just a quick update. I tried to reset the jumping after clicking on the button. It worked in regards to the suuuper high jumping but not in regards to the “hold-jump-down” mechanic. Here’s a video of the difference.

I’m thinking there must be some difference in the way Unity is checking a Input.GetButton and a UI Button.

immenseagitatedaardwolf

I have variable jump in game (and also double jump) and it can be controlled either by keys or by buttons on screen. Here is how it works:
1] I read jump button down and up in separate varaibles (I call ReadInput() from Update()):

    // -----------------------------------------------------------
    private void ReadInput() {

        // jump
        if (PlayerInput.GetButtonDown(PlayerInput.Action.Jump)) {
            _jumpKeyDown = true;
        }

        if (PlayerInput.GetButtonUp(PlayerInput.Action.Jump)) {
            _jumpKeyUp = true;
        }

             :
             :

    }

2] In FixedUpdate() I call Jump(). I have these remarks:

  • I start jump if jump down was triggered and player is grounded and minimum required time since last jump passed or is double jump possible,
  • If jump key/button is released, I decrease velocity by half (if player is going up),
  • finally, If jump key is still down and player is going up, I clear it too. But I do not clear it if he is already falling. This is because if user presses button 1-2 pixels above ground, player is not grounded and will not jump. It looks like game is not responsive. So, I allow user to pres jump button even while still falling down and when player lands and is grounded and jump key is still down, player will immediately jump again.
    // -----------------------------------------------------------
    private Vector2 Jump(Vector2 velocity) {
        if (_isDead) {
            return velocity;
        }

        if (_jumpKeyDown && ((_playerController.Grounded && Time.time >= _timeForNextJump) || _doubleJumpPossible)) {
            velocity.y = _playerController.Grounded ? _jumpTakeOffSpeed : _doubleJumpTakeOffSpeed;
            _timeForNextJump = Time.time + 0.05f;

            if (_playerController.Grounded) {
                _doubleJumpPossible = true;
            } else {
                _doubleJumpPossible = false;
            }

            _animator.SetTrigger("jump");
            AudioManager.Instance.PlayOneShotSound(_heroSFX.AudioMixerGroup, _heroSFX[SFX_JUMP], transform.position, _heroSFX.Volume, _heroSFX.SpatialBlend);
            ParticlesOnJump();

            _jumpKeyDown = false;
        }

        if (_jumpKeyUp) {
            // player is going up
            if (velocity.y > 0) {
                velocity.y *= 0.5f;
            }

            _jumpKeyDown = false;
            _jumpKeyUp = false;
        }


        // if key for jump is still down (not processed above) and player is going up, then clear it
        if (velocity.y > 0) {
            _jumpKeyDown = false;
        }


        return velocity;
    }