Solved - 2D Jumping issue

Well, I have a code and I have a problem with it. So, when i press a little bit faster the jump button I’ve made more times, and then when i release it, the player keeps jumping and he doesn’t stop, It’s like he is jumping repeatedly. btw. here’s my code, if you can help me I’ll be glad… Thanks

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : Character {

    private static Player instance;

    private float direction;

    private bool move;

    private float btnHorizontal;

    public static Player Instance
    {
        get
        {
            if (instance == null)
            {
                instance = GameObject.FindObjectOfType<Player> ();
            }
            return instance;
        }
       
    }

    [SerializeField]
    private Transform[] groundPoints;

    [SerializeField]
    private float groundRadius;

    [SerializeField]
    private LayerMask whatIsGround;

    [SerializeField]
    private bool airControl;

    [SerializeField]
    private float jumpForce;

    public Rigidbody2D MyRigidbody { get; set; }

    public override void Start ()
    {
        base.Start ();
        MyRigidbody = GetComponent<Rigidbody2D> ();
    }

    void Update()
    {
        HandleInput();
    }

    void FixedUpdate () {
        {
            float horizontal = Input.GetAxis ("Horizontal");

            OnGround = IsGrounded ();

            if (move)
            {
                this.btnHorizontal = Mathf.Lerp (btnHorizontal, direction, Time.deltaTime * 2);
                HandleMovement (direction);
                Flip (direction);
            }
            else
            {
                HandleMovement (horizontal);

                Flip (horizontal);
            }
               
            HandleLayers ();
        }
    }

    private void HandleMovement(float horizontal)
    {
        if (MyRigidbody.velocity.y < 0)
        {
            MyAnimator.SetBool ("land", true);
        }
        if (!Attack && !Slide || (OnGround || airControl))
        {
            MyRigidbody.velocity = new Vector2 (horizontal * movementSpeed, MyRigidbody.velocity.y);
        }
        if (Jump && MyRigidbody.velocity.y == 0)
        {
            MyRigidbody.AddForce(new Vector2(0, jumpForce));
        }

        MyAnimator.SetFloat ("speed", Mathf.Abs (horizontal));
    }

    private void HandleInput()
    {
        if (Input.GetKeyDown (KeyCode.Space))
        {
            MyAnimator.SetTrigger ("jump");
        }
        if (Input.GetKeyDown (KeyCode.Return))
        {
            MyAnimator.SetTrigger ("attack");
        }
        if (Input.GetKeyDown (KeyCode.AltGr))
        {
            MyAnimator.SetTrigger ("slide");
        }
        if (Input.GetKeyDown (KeyCode.T))
        {
            MyAnimator.SetTrigger ("throw");
        }
        if (Input.GetKeyDown (KeyCode.LeftAlt))
            {
                MyAnimator.SetTrigger ("lupercut");
            }
        if (Input.GetKeyDown (KeyCode.LeftControl))
            {
                MyAnimator.SetTrigger ("lkick");
            }
        if (Input.GetKeyDown (KeyCode.RightControl))
            {
                MyAnimator.SetTrigger ("rkick");
            }
        if (Input.GetKeyDown (KeyCode.Tab))
        {
            MyAnimator.SetTrigger ("rpunch");
        }
    }

    private void Flip(float horizontal)
    {
        if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
        {
            ChangeDirection ();
        }
    }

    private bool IsGrounded()
    {
        if (MyRigidbody.velocity.y <= 0)
        {
            foreach (Transform point in groundPoints)
            {
                Collider2D[] colliders = Physics2D.OverlapCircleAll (point.position, groundRadius, whatIsGround);

                for (int i = 0; i < colliders.Length; i++)
                {
                    if (colliders [i].gameObject != gameObject)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    private void HandleLayers()
    {
        if (!OnGround) {
            MyAnimator.SetLayerWeight (1, 1);
        }
        else
        {
            MyAnimator.SetLayerWeight (1, 0);
        }
    }

    public override void ThrowKnife(int value)
    {
        if (OnGround && value == 1 || !OnGround && value == 0)
        {
            base.ThrowKnife (value);
        }
    }

    public void BtnJump()
    {
        MyAnimator.SetTrigger ("jump");
        Jump = true;
    }

    public void BtnAttack()
    {
        MyAnimator.SetTrigger ("attack");
    }

    public void BtnSlide()
    {
        MyAnimator.SetTrigger ("slide");
    }

    public void BtnLUpercut()
    {
        MyAnimator.SetTrigger ("lupercut");
    }

    public void BtnLKick()
    {
        MyAnimator.SetTrigger ("lkick");
    }

    public void BtnRKick()
    {
        MyAnimator.SetTrigger ("rkick");
    }

    public void BtnRPunch()
    {
        MyAnimator.SetTrigger ("rpunch");
    }

    public void BtnMove(float direction)
    {
        this.direction = direction;
        this.move = true;
    }

    public void BtnStopMove()
    {
        this.direction = 0;
        this.btnHorizontal = 0;
        this.move = false;
    }

    private void ResetValues()
    {
        Attack = false;
        Slide = false;
        Jump = false;
    }
}

The variable ‘Jump’ doesn’t seem to be reset. I see a method to reset values, but couldn’t spot it being called in the posted code.

You would be better off adding key bindings in InputManager and using them. It would add the easy ability for players and yourself to change key bindings.

I’m new in unity. What did you mean by couldn’t spot it being called? :\

I don’t know what are key bindings in InputManager… Can you tell me pls what did you mean by changing key bindings? Thanks

Well, when i call the ResetValues() in Update metod, now when i press the jump button couple of times, the player jumps, and after i jumped with the jump button couple of times, when i press again jump button he doesn’t jump anymore. Like the jump button won’t work after i jumped once or couple of times…

I won’t say I looked to see where ResetValues should go. My example doesn’t need that right now, so just remove it from your Update() temporarily to check this.
Where you have this code, add a line:

if (Jump && MyRigidbody.velocity.y == 0)
{
   MyRigidbody.AddForce(new Vector2(0, jumpForce));
   // Add this line here:
   Jump = false;
}

I think that’s all you need. What I was trying to say before was that it didn’t look like you were ever setting jump to false, which meant you could jump a lot.

Though, now when I am looking at it, again, it’s odd because the code checks for a y velocity of 0, which shouldn’t be the case when you’re jumping.

Thanks alot, now the problem is solved, but there’s only little bug while I’m jumping, it’s like when I jump he jumps only one more time by itself. But thank you very much methos you helped me alot. :wink:

Okay, perhaps you could add a check if they’re on the ground (in addition to or to replace the velocity.y == 0)
That might help?

sorry dont know what did you mean :\

Okay – you already have a variable ‘OnGround’.
So it could be this:

if (Jump && MyRigidbody.velocity.y == 0 && OnGround)

or (if this works):

if (Jump && OnGround)

that’s what I meant. You could try that and see if it fixes the extra jump.

i replaced it with:

if (!Attack && !Slide || (OnGround || airControl))
        {
            MyRigidbody.velocity = new Vector2 (horizontal * movementSpeed, MyRigidbody.velocity.y);
        }

and both of code doesn’t fix that

now i replaced it with:

if (Jump && MyRigidbody.velocity.y == 0)
        {
            MyRigidbody.AddForce(new Vector2(0, jumpForce));
            Jump = false;
        }

and both of lines won’t work either

I’m a little confused… you changed some lines that had 1 error, then changed them back but now nothing is working?

First I’ve changed lines of

if (!Attack && !Slide || (OnGround || airControl))
        {
            MyRigidbody.velocity = new Vector2 (horizontal * movementSpeed, MyRigidbody.velocity.y);
        }

Then I returned lines as they were before, then both of lines I tried to replace it with “if (Jump && MyRigidbody.velocity.y == 0)” in code:

if (Jump && MyRigidbody.velocity.y == 0)
        {
            MyRigidbody.AddForce(new Vector2(0, jumpForce));
            Jump = false;
        }

and both of your lines doesn’t fix the jump

Okay, I wasn’t suggesting that you change the first line you posted, but the second one (to what I posted).

If you’re still stuck, and you can attach a simple scene as a unity package, I can try to look at it for you.

1 Like

There you go. You will see in scenes folder a scene called Level1, open it and after you hit play, try pressing the jump button repeatedly as fast as you can… after that he jumps by itself only once you’ll see. btw. there’s a weird little bug in sprite anim, most of times when he jumps, just ignore it. Here I’ve made a link https://files.fm/u/v9zgjwcs.

If you change this, you won’t allow more jumps.

public void BtnJump()
{
   if (!OnGround) return;
   MyAnimator.SetTrigger ("jump");
   Jump = true;
 }

As for your other weird glitch, do you mean when landing? It’s possible that your statemachine behaviour is doing that. I didn’t spend a lot of time looking at it, but that appears to be the only other thing affecting that bool, if that’s even what you were talking about.

I’m very grateful for your help… but this jump glitch still seem to appear… he’s still doing extra jump, like he’s still jumping that one more jump, and without animation. that other weird glitch is solved,

Even with the code I posted? Did you replace your current ‘BtnJump’ method with that one?
When I tested your code, if I hit the button 2+ times, the character would jump, then land and jump again without me pressing jump (after the landing). With the posted code change, no matter how many times I hit jump, it only jumped once. I could only jump again after landing.