Added Long Jump to Player, now he can't double jump properly

So now I’ve added the long Jump to the player I want to let him double jump after he’s done a long jump. The problem is when I look in the IDE when he does a short jump, he has 1 ‘jumpsRemaining’ left. But when hold the key long enough to long jump then the jumpsRemaining goes from 1 to 0. Just wondering what I’ve done in my code here because to me this looks sound. Thanks in advance :slight_smile:

public class Jump : AbstractBehaviour {

    public float jumpSpeed;
    public float jumpDelay = .1f;
    public int jumpCount = 2;

    protected float lastJumpTime = 0;
    public int jumpsRemaining = 0;


    // Use this for initialization
    void Start () {
       
    }

    // Update is called once per frame
    protected virtual void Update()
    {
        var canJump = inputState.GetButtonValue(inputButtons[0]);
        var holdTime = inputState.GetButtonHoldTime(inputButtons[0]);
        if (collisionState.standing)
        {
            if (canJump && holdTime < .1f)
            {
                jumpsRemaining = jumpCount - 1;
                OnJump();
            } 
            }
        else
        {
            if (canJump && holdTime < .1f && Time.time - lastJumpTime > jumpDelay)
            {
                if (jumpsRemaining > 0)
                    OnJump();
                jumpsRemaining = 0;
            }
        }
    }
    protected virtual void OnJump()
    {
        var vel = rb2d.velocity;
        lastJumpTime = Time.time;
        rb2d.velocity = new Vector2(vel.x, jumpSpeed);
    }
}
public class LongJump : Jump {

    public float longJumpDelay = .15f;
    public float longJumpMultiplier = 1.5f;
    public bool canLongJump;
    public bool isLongJumping;

    protected override void Update()
    {
        var canJump = inputState.GetButtonValue(inputButtons[0]);
        var holdTime = inputState.GetButtonHoldTime(inputButtons[0]);

        if (!canJump)
            canLongJump = false;

        if (collisionState.standing && isLongJumping)
        {
            isLongJumping = false;
        }

       base.Update();
        if (canLongJump && !collisionState.standing && holdTime > longJumpDelay)
        {
            var vel = rb2d.velocity;
            rb2d.velocity = new Vector2(vel.x, jumpSpeed * longJumpMultiplier);
            canLongJump = false;
            isLongJumping = true;
        }
    }
    protected override void OnJump()
    {
        base.OnJump();
        canLongJump = true;
    }
}

Check if your keyboard might be repeating while you hold it, and thereby “consuming” your other jump.

How do you mean repeating? I’ve got a script that tracks hold time and it’s tracked the jump button as one full input if that’s what you mean?

i think its because canLongJump is false and nothing sets it to true. ONly the overrided method OnJump does, and nothing calls it. Your base.Update is calling the base Onjump

Edit: Just realized you meant you are successfully long jumping, and somehow the jump counter is being set to 0 during this?

Its hard to follow the exact logic of the code without seeing your custom inputState class. Without knowing what booleans those are returning, can’t make definite answers. Also I don’t see anything changing collisionState from standing to something else (jumping?) but I assume it happening.

If canJump is returning true as long as the button is being held down, then your double jumping while waiting for the long jump to kick in… and your just not noticing it because the delay between a double jump and long jump is very short less than .05 seconds.

So when the user first presses down and the canJump will be true and hold time will be around .02s (50fps). So he jumps… now around .12s if your still holding down for a long jump the second part of your baseUpdate is called and a double jump initiates because its been .1 seconds since the first jump started. Now at .15 seconds the long jump initiates and overrides the velocity of the double jump. But you still double jumped so your counter is 0. You just didn’t notice the double jump because .03 seconds later the long jump kicked in.

Now all this is predicated on canJump being true if the button is held down… Is that the case?

Yeah man so I can double jump after I’ve done a short jump but when it kicks into long jump then the jumpsRemaining goes to 0, so it’s maybe reading my longJump as a double jump somehow? I’ll show you my inputClass and hope that helps. And yeah standing is a boolean so it reads it as he’s just standing or he’s not.

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

public class ButtonState
{
    public bool value;
    public float holdTime = 0f;
}

public enum Directions
{
   Right = 1,
   Left = -1

}

public class InputState : MonoBehaviour {

    public Directions direction = Directions.Right;
    public float absVelX = 0f;
    public float absVelY = 0f;

    private Rigidbody2D rb2d;

    void Awake()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        absVelX = Mathf.Abs(rb2d.velocity.x);
        absVelY = Mathf.Abs(rb2d.velocity.y);
    }

    private Dictionary<Buttons, ButtonState> buttonStates = new Dictionary<Buttons, ButtonState>();
   
    public void SetButtonValue(Buttons key, bool value)
    {
        if (!buttonStates.ContainsKey(key))
       
            buttonStates.Add(key, new ButtonState());

        var state = buttonStates[key];
       

        if (state.value && !value)
        {
            Debug.Log("Input " + key + " released" + state.holdTime);
            state.holdTime = 0;
        }
        else if (state.value && value)
        {
            state.holdTime += Time.deltaTime;
            Debug.Log("Input " + key + " held down" + state.holdTime);
           
        }

        state.value = value;
    }
    public bool GetButtonValue(Buttons key)
    {
        if (buttonStates.ContainsKey(key))
            return buttonStates[key].value;
        else
            return false;
    }
        public float GetButtonHoldTime(Buttons key)
    {
        if (buttonStates.ContainsKey(key))
            return buttonStates[key].holdTime;
        else
            return 0;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Buttons
{
    Right,
    Left,
    Up,
    Down,
    A,
    B
   
}

public enum Condition
{
    Greaterthan,
    Lessthan,
}

[System.Serializable]
public class InputAxisState
{
    public string axisName;
    public float offValue;
    public Buttons button;
    public Condition condition;
    public bool value
    {get
        {
            var val = Input.GetAxis(axisName);
            switch (condition)
            {
                case Condition.Greaterthan:
                    return val > offValue;
                case Condition.Lessthan:
                    return val < offValue;  

            }
            return false;
        }

    }
}
public class InputManager : MonoBehaviour {

    public InputAxisState[] Inputs;
    public InputState inputState;

    // Use this for initialization
    void Start () { 
    }
   
    // Update is called once per frame
    void Update () {
        foreach (var input in Inputs)
        {
            inputState.SetButtonValue(input.button, input.value);
        }
    }
}

So will this line be true if the button is held down or not? Seems like a simple starightforward question. Is it true from being held down or just from one frame that its pushed:

 var canJump = inputState.GetButtonValue(inputButtons[0]);

If its true whenever the jump button is held down, then my explanation in the previous post is why your consuming jump charges when long jumping

Yeah it’s true if the button’s held down. Though from reading your first answer I still don’t see exactly what I have to do, is it okay if you could explain a little further?