Linked Questions

Popular Questions

Question about Double Jump and Collision in Unity

Asked by At

I have just started to learn how to make a simple 2D platformer game in Unity, and I have watched Blackthornprod 2D Platformer movement video to learn how to make a character move and jump. So far I was able to understand most of the video, however, I have met some problem with the Jumping part.

Now, as far as I understand in his video, to make a character jump, I need to detect whether the character is touching the ground or not. To do that I need to create a little circle under the player's feet to see if it overlaps the ground, like this

So, here is the code:

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

public class PlayerController : MonoBehaviour
{
    public float JumpForce;       // jumping force

    private bool isGrounded;      //if the player is touching the ground
    public Transform GroundCheck; //object that contains the position of the 
                                  //"circle"
    public LayerMask GroundLayer; //the layer that the "circle" collide with
    public float radius;          //radius of the circle
    public float BaseNumOfJumps;  //maximum number of jumps
    private float NumOfJumps;     //current number of jumps


    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        NumOfJumps = BaseNumOfJumps;
    }

    void FixedUpdate()
    {
        //check the collision between the "circle" and the ground
        isGrounded = Physics2D.OverlapCircle(GroundCheck.position, 
        radius,GroundLayer);

       //here is the horizontal movement update part, but they are 
       //irrelevant so I cut them off

    }

    void Update()
    {
        //if the player touches the ground, reset the number of jumps
        if (isGrounded)
        {
            NumOfJumps = BaseNumOfJumps;
        }

        //when jumping, decrease the number of jumps
        if (Input.GetKeyDown(KeyCode.UpArrow) && NumOfJumps > 0)
        {
            rb.velocity = Vector2.up * JumpForce;
            NumOfJumps--;
        }
    }

}

Here is where the problem began, the actual maximum number of jumps is always higher than the value I entered. So for example, if I put BaseNumOfJumps = 2, then I can jump 3 times instead of 2, similarly, if BaseNumOfJumps = 1 then I can jump 2 times and so on.

After a while, I found out that because the size of the circle is always a tad bit larger than the actual player's feet, when I jump, the was a moment in between where the player's feet is int the air, but the circle still overlaps with the ground, which reset the current number of jumps (aka NumOfJumps in my code) and make my character able to do one more jump than the number entered in BaseNumOfJumps. I don't know if it was true or not, but here was what I imagined. This comment under the video also described the same problem.

While Blackthornprod already mentioned those value as "extra jumps", so if I enter "1" in that value, I will jump twice, "2" and I will jump 3 times, etc. I still met some difficulties in making the number of jumps consistent. What if my character just slides off the ground without jumping like this? The circle wouldn't collide with the ground and I will be able to jump the exact number of jumps I entered in BaseNumOfJumps, in short:

If the maximum number of jumps I entered is 2, I will be able to (again, this is just my guess, so I could likely be wrong):

Which of course create some inconsistency. I have searched other tutorials about jumping and colliding, but most of them either use other forms of checking collision (like OnCollisionStay, OnCollisionEnter) or use the same method I used but didn't go deep into explaining it (So basically they are the same as in Blackthornprod's video)

So how can I solve this problem, how can I change the radius of the "circle" so that it leaves the ground the same moment the player's feet leaves when they jump? Or should I use other forms of collision checking like I mentioned before, and if so, what are their difference and which is the most effective?

This is my first question here, I know it's a bit long and confusing since I am not familiar with English, but I will really appreciate if anyone can help.

Related Questions