# How do I detect if my object is grounded?

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"))
{
NumberJumps += 1;
}
}
controller.Move(horizontalMove * Time.fixedDeltaTime, false, false);
}
}


In the inspector it always says that Isgrounded is false.

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)
{