SweepTest to check if grounded

void FixedUpdate () {

		if (Input.GetKeyDown (KeyCode.Space) && IsGrounded ())
			Jump ();

		rigidbody.MovePosition (transform.position + heading * Time.deltaTime);
	}

	void Jump () {

		rigidbody.AddForce (Vector3.up * jumpForce, ForceMode.Impulse);
	}

	bool IsGrounded () {
		RaycastHit hit = new RaycastHit ();
		return rigidbody.SweepTest (Vector3.down, out hit, 0.1F);
	}

Hi! Really quite new to Unity here and I’m experimenting a little with different things.

I would like to make my character able to jump but only when actually on the ground.

Previously I created a “Feet” Quad GameObject and childed it to the player, and used SendMessage to make the player GameObject set a ‘grounded’ variable to true when OnTriggerEnter was called. However, the solution felt a bit ‘clunky’ and often the controls felt a bit ‘sticky’.

I figured this was because of some sort of desync between the Feet Quad and the Player GameObject. After a bit of Googling I came across many, many examples calling for a RayCast downwards. However I’m not satisfied by that since it leave ‘holes’ in the area I want to check. So I found out about SweepTest and decided to give it a try.

However, my IsGrounded () function never returns true, thus sticking my player to the ground :frowning:

Does anyone have any idea why this may be?

Notes: My player’s Rigidbody has constrained rotation (though I tried turning that off so this isn’t the problem, probably) and a BoxCollider attached to it. The ground is a primitive Plane. Thinking that might have been the problem I dropped my player onto a primitive Cube, but it refused to jump even then.

Im not sure what you mean by “Holes” when using raycast.

You should ( or can ) use a normal raycast downwards like this

RaycastHit hit;

bool isGrounded = false;

// ( ATTENTION: if your player transform is in the middle of the character, then add the half height of your player to your maxRayDistance)
float maxRayDistance = 0.2f; //You can change how much down checks

public LayerMask layerToCheck; // In inspector you can tick which layer should be checked by the raycast, you can change objects layer in inspector and add new layers 

void Update()
{
   CheckIfGrounded(); // Constantly check if grounded
}

void CheckIfGrounded()
{
    if(Physics.Raycast(transform.position, Vector3.down,out hit, maxRayDistance,layerToCheck))
    {
        //If an object with this layer is being hit then make isGrounded true
        isGrounded = true;
    }
    else // Else if not hitting anything, set isGrounded false
    {
        isGrounded = false;
    }
}

And then you can do if input and if isGrounded, you can jump

hope it helps