0
\$\begingroup\$

I'm having some trouble with vertical movement. I'm trying to add double-jumping but none of the scenarios online seem to be working, and I can only ever manage to get a single jump. Here's my code:

using UnityEngine;
using System.Collections;

public class Moving : MonoBehaviour {
//public float speed;
CharacterController controller;
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
public bool candoublejump = true;
public int jumptime = 0;
private Vector3 moveDirection = Vector3.zero;
// Use this for initialization
void Start () {
    controller  = GetComponent<CharacterController>();
}

void FixedUpdate() {
    if (controller.isGrounded) {
        moveDirection = new Vector3 (Input.GetAxis ("Horizontal") * 2000, 0, Input.GetAxis ("Vertical") * 2000);
        moveDirection = transform.TransformDirection (moveDirection);
        moveDirection *= speed;
    }
    if (Input.GetButton ("Jump")) {
        if (controller.isGrounded) {
            moveDirection.y = 0;
            moveDirection.y = jumpSpeed;
            candoublejump = true;
        } else {
            if (candoublejump) {
                candoublejump = false;
                moveDirection.y = jumpSpeed;
            }
        }
    }
    moveDirection.y -= gravity * Time.deltaTime;
    controller.Move(moveDirection * Time.deltaTime);
}
}

Is there something wrong with my keyboard maybe? My theory is that it's checking for the double jump in the split second after you did the first one, which isn't helpful because you're still holding the jump button.

\$\endgroup\$
2
  • \$\begingroup\$ Can you tell us what's wrong with the behaviour you get in game? How does it differ from what you want? \$\endgroup\$
    – DMGregory
    Commented Jan 25, 2019 at 15:13
  • \$\begingroup\$ @DMGregory I can only ever single jump, nothing I do seems to be able to add another jump \$\endgroup\$ Commented Jan 25, 2019 at 15:15

1 Answer 1

1
\$\begingroup\$

There are two problems here.

First, as you surmised, GetButton() asks "is the button currently in the pressed state?" So unless the player manages to tap the button so precisely that it's pressed for exactly one frame, you'll get multiple hits from the button being held down.

To fix this, you can use GetButtonDown(), which asks "did the button enter the pressed state this frame?"

But there we run into problem number two: you're checking for jump input, which is true for exactly one frame, in FixedUpdate, which can be called zero or multiple times per frame. This can lead to missed or double-handled inputs.

I discuss this input timing issue and a way to solve it in this earlier answer. In your case it would look something like this:

bool hasHandledInputThisFrame = false;

void HandleInput(bool isFixedUpdate) {
    bool hadAlreadyHandled = hasHandledInputThisFrame;
    hasHandledInputThisFrame = isFixedUpdate;
    if(hadAlreadyHandled)
        return;

    // Handle instantaneous inputs & physics effects exactly once per frame.
    if (Input.GetButton ("Jump")) {
        if (controller.isGrounded) {
            moveDirection.y = 0;
            moveDirection.y = jumpSpeed;
            candoublejump = true;
        } else {
            if (candoublejump) {
                candoublejump = false;
                moveDirection.y = jumpSpeed;
            }
        }
    }
}

void FixedUpdate() {
    HandleInput(true);

    if (controller.isGrounded) {
        var inputDirection = new Vector3 (Input.GetAxis ("Horizontal") * 2000, 0, Input.GetAxis ("Vertical") * 2000);
        var newVelocity = transform.TransformDirection (inputDirection);
        newVelocity *= speed;

        // Preserve vertical velocity due to jump/falling.
        newVelocity.y = moveDirection.y;
        moveDirection = newVelocity;
    }

    moveDirection.y -= gravity * Time.deltaTime;
    controller.Move(moveDirection * Time.deltaTime);
}

void Update() {
    HandleInput(false);
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .