My double jump only works after I do a grounded jump. If I walk off a ledge the player just falls with no double jump. How do I fix this?

My double jump only works after I do a grounded jump. If I walk off a ledge the player just falls with no double jump.

How do I fix this?

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

public class PlayerMovement : MonoBehaviour
{
    private Rigidbody2D rb;
    private SpriteRenderer sprite;
    private Animator anim;
    private Collider2D coll;
    private bool doubleJump;
    private float dirX = 0f;
    [SerializeField] private LayerMask jumpableGround;
    [SerializeField] private float moveSpeed = 22f;
    [SerializeField] private float jumpForce = 12f; 
    [SerializeField] private float doubleJumpingForce = 8f;
    private enum MovementState {idle, running, jumping, falling}

    private void Start()
    {
       rb = GetComponent<Rigidbody2D>();
       sprite = GetComponent<SpriteRenderer>();
       coll = GetComponent <BoxCollider2D>();
       anim = GetComponent<Animator>();
    }

    private void Update()
    {
        dirX = Input.GetAxis("Horizontal");
        rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y); 

        if (IsGrounded() && !Input.GetButton("Jump"))
        {
            doubleJump = false;
        }

             if (Input.GetButtonDown("Jump"))
        {
            if (IsGrounded() || doubleJump)
            {
                rb.velocity = new Vector2(rb.velocity.x, doubleJump ? doubleJumpingForce : jumpForce);

                doubleJump = !doubleJump;
            }
        }

        UpdateAnimationState();
    }

    private void UpdateAnimationState()
    {
        MovementState state;
        
        if (dirX > 0f) 
        {
            state = MovementState.running;
            sprite.flipX = false;
        }
        else if (dirX < 0f) 
        {
            state = MovementState.running; 
            sprite.flipX = true;   
        }
        else
        {
            state = MovementState.idle;
        }
        if (rb.velocity.y > .1f)
        {
            state = MovementState.jumping;
        }
        else if (rb.velocity.y < -.1f)
        {
            state = MovementState.falling;
        }

        anim.SetInteger("state", (int)state);
    }
    private bool IsGrounded()
    {
        return Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, .1f, jumpableGround);
    }
}

Hi Neurocase,

It looks like you only set the doubleJump variable to false if the character is grounded and the player is not pressing the jump button. Which means that if the player doesn’t press the jump button (walks off the ledge) while being grounded, the if condition would not be true, hence, the doubleJump variable does not change.

Also, doubleJump = !doubleJump might introduce unexpected behaviour.

One approach to solve this would be to check if you have just recently been grounded, and only change the doublejump variable to false after using double jump.
The code would looks something like this:

private bool wasGrounded;

private void Start()
{
    // Other initializations
    wasGrounded = false;
}

private void Update()
{
    dirX = Input.GetAxis("Horizontal");
    rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y); 

    // Check if the player has just left the ground
    if (wasGrounded && !IsGrounded())
    {
        doubleJump = true;
    }

    if (Input.GetButtonDown("Jump"))
    {
        if (IsGrounded() || doubleJump)
        {
            rb.velocity = new Vector2(rb.velocity.x, doubleJump ? doubleJumpingForce : jumpForce);

            // Reset double jump only after using it
            if (doubleJump)
            {
                doubleJump = false;
            }
        }
    }

    if (IsGrounded())
    {
        doubleJump = false;
    }

    wasGrounded = IsGrounded(); // Update the wasGrounded status for the next frame
    UpdateAnimationState();
}

Thank you so much!!! It worked!!!