- Home /
When i press Jump, i am allowed to double/triple jump even though i called for a capsule check?
Hey guys, im a little new to Unity so i dont quite understand how the engine works yet. Anyways I am trying to get it to where when the jump button is pressed, an impulse force is added only once to make the player jump until it detects collision with a ground layer via capsule check. This works, unfortunately, if the user continuously hits the jump button, the player object with "jiggle" upward with little mini jumps. I am honestly so confused on why my code doesnt work. I would greatly appreciate any help or advice i can get :)
Here is the code: public class playerJump : MonoBehaviour {
// Set variables.
private float jumpVelocity;
public bool grounded;
[SerializeField]
private CapsuleCollider col;
[SerializeField]
private Rigidbody rb;
// Pass in variables.
public void Jump(float _jumpVelocity)
{
jumpVelocity = _jumpVelocity;
}
// Sets new ground layer.
public LayerMask ground;
// Checks to see if the player is touching the ground.
void isGrounded() { if (Physics.CheckCapsule((col.bounds.center), new Vector3(col.bounds.center.x, col.bounds.min.y, col.bounds.center.z), col.radius, ground)) grounded = true; else grounded = false; }
private void OnCollisionEnter(Collision collision)
{
if (gameObject.layer == ground)
grounded = true;
}
private void OnCollisionExit(Collision collision)
{
if (gameObject.layer != ground)
grounded = false;
}
// Jumping function
void performJump()
{
isGrounded();
if (grounded && Input.GetButtonDown("Jump"))
rb.AddForce(transform.up * jumpVelocity,ForceMode.Impulse);
}
// Use this for initialization
void Start () {
col = GetComponent<CapsuleCollider>();
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
performJump();
}
}
Answer by ignacevau · Aug 18, 2018 at 09:54 PM
I would like to mention that your
OnCollisionExit
method is completely useless since the bool ground gets updated every frame before it's used.You are using
OnCollisionEnter / OnCollisionExit
as well asPhysics.CheckCapsule
, you only need one of them.
The easiest way to achieve the result is by using OnCollisionEnter / OnCollisionExit
and updating the bool grounded on every collision.
public float jumpVelocity;
Rigidbody rb;
bool grounded;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("Ground"))
{
grounded = true;
}
}
private void OnCollisionExit(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
grounded = false;
}
}
void PerformJump()
{
rb.AddForce(transform.up * jumpVelocity, ForceMode.Impulse);
}
private void FixedUpdate()
{
if(grounded && Input.GetKeyDown(KeyCode.Space))
{
PerformJump();
}
}
Make sure to add the "Ground" tag to your ground object
You could also make this work with Physics.CheckCapsule
and performance-wise, it would probably be more efficient (in most cases not noticeable though).
@ignacevau Thank you so much, i didnt realize i was still using the onCollisionenter/exit function! I appreciate you! I would like to use Physics.CheckCapsule if at all possible so that i can specify to only jump if the collision occurs on the bottom of my player object. I altered the code to fit your recommendations, unfortunately i have come across another problem. Now my player will not jump at all. Do you think you could explain what is happening to me? :)
public class playerJump : $$anonymous$$onoBehaviour {
// Set variables.
private float jumpVelocity;
public bool grounded;
[SerializeField]
private CapsuleCollider col;
[SerializeField]
private Rigidbody rb;
// Pass in variables.
public void Jump(float _jumpVelocity)
{
jumpVelocity = _jumpVelocity;
}
// Sets new ground layer.
public Layer$$anonymous$$ask ground;
// Checks to see if the player is touching the ground.
private void isGrounded()
{
if (Physics.CheckCapsule((col.bounds.center), new Vector3(col.bounds.center.x, col.bounds.$$anonymous$$.y, col.bounds.center.z), col.radius * 0.9f, ground))
grounded = false;
}
// Jumping function
void performJump()
{
isGrounded();
if (grounded && Input.GetButtonDown("Jump"))
rb.AddForce(transform.up * jumpVelocity,Force$$anonymous$$ode.Impulse);
}
// Use this for initialization
void Start () {
col = GetComponent<CapsuleCollider>();
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
performJump();
}
Answer by firebird127 · Aug 19, 2018 at 10:19 PM
@ignacevau Nevermind! I overlooked a simple typo mistake! i appreciate all of your help!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Jump forward then back initial position 0 Answers
Gravity trouble: Falling slow, jumping fast 1 Answer
how to add force? 2 Answers