- Home /
How to make sure that my cube can only jump when in contact with the ground
I have a rigid body cube, but at the moment, it can repeatedly jump and fly out of the boundaries. How can I make it so that the cube can only jump if it's in contact with the ground?
Here's the code I've written so far.
if(Input.GetButtonDown("I"))
{
rigidbody.velocity.y = 5;
}
Thanks in advance.
Answer by AngryAnt · Feb 04, 2010 at 09:23 AM
You basically have two different ways to solve this issue: Colliders or raycasts.
For both you'll have to first be able to identify ground colliders from other colliders. Use a layer for this.
Example of using colliders:
Create a GameObject as a child of your cube and add a collider to this. Make it a trigger and set it up so that it is slightly larger than the collider on the parent GameObject. We're now able to, in a stable manner, detect whether or not our object is in contact with a surface. To find out if this surface is identified as ground and let your movement script know of this, you should add a script to the child GameObject - structured somewhat like this:
void OnTriggerEnter (Collider other) { if (other.gameObject.layer != LayerMask.NameToLayer ("Ground")) { return; }
m_GroundObjectsList.Add (other);
transform.parent.gameObject.
GetComponent <MovementScript> ().m_Grounded = true;
}
void OnTriggerExit (Collider other) { if (other.gameObject.layer != LayerMask.NameToLayer ("Ground")) { return; }
m_GroundObjectsList.Remove (other);
transform.parent.gameObject.
GetComponent <MovementScript> ().m_Grounded =
m_GroundObjectsList.Count > 0;
}
Example of using raycasts:
This is only a modification to your movement script. It assumes that you're using physics for movement, but you should be able to fairly easily use it anyway if you're not. It also assumes that your character is always in an upright position - that transform.up is always up and that gravity pull is in the opposite direction.
Basically the idea is to fire a raycast downwards every fixed update (or more often if you need it) and if we hit something, we're grounded. Notice that I use gizmos to visualise the raycast used - this makes it easier to tweak the length of the raycast for various models.
The advantage of this over the collider way of doing it is, apart from simplicity, that you'll not appear grounded when colliding with a ground tagged object on your side without actually having landed.
void FixedUpdate () { m_Grounded = Physics.Raycast (transform.position, transform.up * -1, m_GroundCastLength, 1 << LayerMask.NameToLayer ("Ground"));
if (m_Grounded)
{
/* do movement */
if (/* should jump */)
{
m_Grounded = false;
/* do jump */
}
}
}
void OnDrawGizmos () { Gizmos.DrawLine (transform.position, transform.position + transform.up * -m_GroundCastLength); }
Answer by Nicolaj Schweitz · Feb 03, 2010 at 07:32 AM
The CharacterController is probably closer to what you want. It has a boolean "isGrounded", that pretty much checks for what you need.
You might also want to decipher the controller scripts in the standard package that comes with Unity.
Your answer
Follow this Question
Related Questions
rigidbody player jump automatically. 0 Answers
moving with rigidbody without acceleration 0 Answers
how can I make a character fly when holding down the jump button? 1 Answer
Rigidbody Stick To Floor 1 Answer
How to get global up vector? 1 Answer