0
\$\begingroup\$

I am trying to detect when an object is grounded.

My script right now is:

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

public class playermovement : MonoBehaviour
{
    public CharacterController2D controller;
    public Rigidbody2D rb;
    float horizontalMove = 0f;
    public float runSpeed = 40f;
    Vector2 forceapplied;
    public bool isGrounded;
    public float NumberJumps = 0f;
    public float MaxJumps = 2;
    public float jumpHeight = 7f;
    public CircleCollider2D bc;

    void Start()
    {
        forceapplied = new Vector2(0.0f, 30f);
    }

    void Update()
    {
        if(bc.gameObject.name == "Grid") {
            isGrounded = true;
            NumberJumps = 0;
        }
        horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;

        if (NumberJumps > MaxJumps - 1)
        {
            isGrounded = false;
        }
    }

    private void FixedUpdate()
    {
        if (isGrounded)
        {
            if (Input.GetButtonDown("Jump"))
            {
                rb.AddForce(Vector2.up * jumpHeight);
                NumberJumps += 1;
            }
        }
        controller.Move(horizontalMove * Time.fixedDeltaTime, false, false);
    }
}

In the inspector it always says that Isgrounded is false.

Can someone please help?

\$\endgroup\$
3

1 Answer 1

0
\$\begingroup\$

As @DMGregory pointed out, there are soo many tutorials on this subject, but since I have just answered a similar question (https://stackoverflow.com/a/66938817/1405906) I will try to address some parts of your code:

I assume that the collider (bc) is connected to your player. If so, bc.gameObject.name, will always be the name of your player object. That is why isGrounded never is set to true.

if(bc.gameObject.name == "Grid") {
        isGrounded = true;
        NumberJumps = 0;
    }

Physics should be done in FixedUpdate(), so that is good, but you should not try to get the input there. You might miss "one-time" events like a jump since it is not guaranteed that FixedUpdate() will be called in every frame. Move the check to Update() and store the jump flag in a boolean.

bool jump = false;
Update()
{
    if( Input.GetButtonDown("Jump") )
        jump = true;
    ...
}

Since you want to support a double jump (or more), the ground check should only be done before the first jump is launched. Once jumping, the player is in the air and there is no ground - but you still want to be able to do the second jump.

FixedUpdate()
{
    if(jump)
    {
        if( isGrounded || (NumberJumps>0 && NumberJumps<MaxJumps)
        {
            rb.AddForce(Vector2.up * jumpHeight);
            NumberJumps += 1;
        }
        jump = false; // Remember to reset the jump flag.
    }
    controller.Move(horizontalMove * Time.fixedDeltaTime, false, false);
}

Now it should work. For more information on how to do the ground-check, see my answer above, or google. Remember to reset the NumberJumps to 0 as soon as you are grounded. Good luck!

\$\endgroup\$

You must log in to answer this question.

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