double jump works fine but not when falling from a ledge, how to fix it?

i am making a 2d platformer, and i can move my player left and right and also flip its face while doing so, then i added double jump function. it worked well but i have one issue. i want my character to double jump when it is on ground, and if it falls from a ledge then it still should have its double jump feature. i am putting my code below, and i hope if anyone can help me. thanks already.

below is my code

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

public class PlayerMovement : MonoBehaviour
{
public float speed;
public float jumpForce;
private float moveInput;

private Rigidbody2D rb;
private bool facingRight = true;

private bool isGrounded;
public Transform groundCheck;
public float checkRadius;
public LayerMask whatisGround;

private int extraJumps;
public int extraJumpsValue;

void Start()
{
    extraJumps = extraJumpsValue;
    rb = GetComponent<Rigidbody2D>();
}

void FixedUpdate()
{

    isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, whatisGround);

    moveInput = Input.GetAxis("Horizontal");
            rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
    if (facingRight == false && moveInput > 0)
    {
        Flip();
    }
    else if (facingRight == true && moveInput < 0)
    {
        Flip();
    }
}

void Update()
{

    if (isGrounded == true)
    {
        extraJumps = extraJumpsValue;
    }

    if (Input.GetKeyDown(KeyCode.UpArrow) && extraJumps > 0)
    {
        rb.velocity = Vector2.up * jumpForce;
        extraJumps--;
    }
    else if (Input.GetKeyDown(KeyCode.UpArrow) && extraJumps == 0 && isGrounded == true)
    {

    }
}

void Flip()
{

    facingRight = !facingRight;
    Vector3 Scaler = transform.localScale;
    Scaler.x *= -1;
    transform.localScale = Scaler;
}

}

I believe your code is perfectly fine, but since you are falling there is some velocity pushing the character down. Therefore, it looks like the player isn’t moving, but in fact, the player does move with very little velocity upward.

How to Fix This:


Method 1

rb.velocity = new Vector2(0f, 0f);//changes velocity to 0
rb.velocity = Vector2.up * jumpForce;//moves character with initial velocity 0

Method 2 (Recommended)

rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);//moves player upward regardless of velocity

I hoped that helped :slight_smile:


Edit: After trying out the code you sent me it worked fine, but the ‘jumpForce’ was too low. I set the variable (‘jumpForce’) to 30 and it worked just fine. I coincidently I came across this video, the nostalgia from seeing this. Anyways, I couldn’t figure out why you are having issues if ‘jumpForce’ isn’t the case.

I recommend copying these 2D Rigidbody settings:
168518-capture.png

I created another script similar to the original, but probably much more readable for a beginner.

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

public class RevisedPlayerMovement : MonoBehaviour
{
    [SerializeField] private float speed = 8f;//default is 8
    [SerializeField] private float jumpForce = 30f;//default is 30
    [SerializeField] private int maxJumps = 2;//default is 2
    [SerializeField] private int jumps = 0;//the amount of jumps player has done
    private bool isGrounded = true;//Checks if player is touching the ground - default true
    private bool facingRight = true;//Checks if player is looking right - default true

    SpriteRenderer sr;//the player's sprite renderer
    Rigidbody2D rb;//the player's rigidbody


    // Start is called before the first frame update
    void Start()
    {
        /*Get Components - SpriteRenderer & Rigidbody2D*/
        sr = GetComponent<SpriteRenderer>();
        rb = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        Move();
    }

    
    private void OnCollisionEnter2D(Collision2D col)
    {
        /*When Colliding With The Ground*/
        if (col.gameObject.tag == "ground") {
            isGrounded = true;
            jumps = 0;
        }
    }

    private void Move() {
        /*Jump*/
        if (Input.GetKeyDown(KeyCode.UpArrow) && jumps < maxJumps) {
            isGrounded = false;
            jumps++;
            rb.velocity = Vector2.zero;
            rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        }

        /*Moves Left and Right*/
        if (Input.GetKey(KeyCode.RightArrow))//right
        {
            rb.velocity = new Vector2(speed, rb.velocity.y);
            facingRight = true;
        }
        if (Input.GetKey(KeyCode.LeftArrow))//left
        {
            rb.velocity = new Vector2(-speed, rb.velocity.y);
            facingRight = false;
        }

        Flip();
    }

    /*Flips Sprites On X-Axis Using SpriteRenderer Component*/
    private void Flip() {
        if (!facingRight)
            sr.flipX = true;
        else
            sr.flipX = false;
    }
}

Two things to note:

-[SerializeField] just makes the variable visible in the inspector, so don’t worry about it too much.

-The variable isGrounded isn’t used in any of the conditions (if-statements), but I included in case you need it for the future.

@muhammadaliawan96 Let me know if you still have troubles, I will create a prefab that you can download that should work when imported to your project.

@UnityToMakeMoney sir my apologies, i tried your code, i started a new clean project and used your code and all the settings you stated in rigidbody2d, the thing is, it now jumps twice while falling off the platform, the only issue now i face is, after jumping twice for 1st time, it cant jump anymore, i tried different things with the code, but it is not working, sir can you please help me in this regard?
i am already thankful to you for what you did already.