- Home /
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 :(
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.
Answer by AngryBurritoCoder · Jul 05, 2015 at 12:01 PM
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
What I meant by "holes" is that doing a single raycast like this can result in situations like this:
http://puu.sh/iNS7h/365c461823.png
which is undesirable.
Even if I were to create a RayCast in all four corners there would still be moments, for example if the player finds themselves on a very thin tightrope, during which the player could not jump despite being grounded:
http://puu.sh/iNSdE/3f6b656892.png
This is why I would like to do what's basically a "square cast" or "cube cast" downwards.
i see what you mean, well you also have the option of using the collider on your character as the thing that checks for ground. Basically you check if your character collider is colling with anything from bottom to something like 0.2f of height up the collider and if it is ground or anything you can jump off then you make isGrounded = true.. Or you can use character controller xd, i was always against rigidbody controllers unless it uses physics for most of the game.
I'll definitely try this, thanks :)
Also I wanted to use Rigidbody because a) I'd like some level of ragdoll physics later during explosions for example and b) I wanted some kind of an arc to the jump.