3
\$\begingroup\$

Does anyone have a better way to make an object with a rigidbody check for ground and then jump, right now I wrote a script where a raycast is cast downwards and it checks for distance but then I discovered that a player can still jump when close to the ground and when I decrease the distance amount on raycast then the jumping works a few times (5 or 6) and then stops working, so I had to increase the distance a bit and add a delay so the player can't jump for some time after a jump. But I think there might be a better way of doing it. So does anyone have suggestions on how can I improve my script or what other method I can use to make a character with a rigidbody to check if grounded and jump?

\$\endgroup\$
  • \$\begingroup\$ What does "stops working" mean exactly? \$\endgroup\$ – VaTTeRGeR Aug 10 '15 at 9:27
  • \$\begingroup\$ It means that when I press space the player isn't jumping \$\endgroup\$ – Vadim Tatarnikov Aug 10 '15 at 9:31
  • 1
    \$\begingroup\$ ok, seems like your ray loses contact, you could check for velocity. player has a low z-velocity -> enable jump. This works if your player is jumping from horizontal surfaces only. You could check with the longer ray in addition to checking the velocity to be more certain. \$\endgroup\$ – VaTTeRGeR Aug 10 '15 at 9:40
  • \$\begingroup\$ @VaTTeRGeR - That idea actually works a lot better than I thought it would. One small problem - at the apex of your jump, your velocity will be near zero. I handled this by requiring two frames in a row of y-velocity being under 0.01f. Can probably trip this up by running up or down hill or something, but eh, works well enough for now. Maybe my game just won't have hills. Who knows. \$\endgroup\$ – ArtOfWarfare Feb 17 '18 at 4:04
2
\$\begingroup\$

Here is a simplified example of how you could implement a check to see if your gameObject is grounded or not. It is not perfect, but should probably work for your situation:

bool Grounded;

void OnCollisionStay2D(Collision2D collider)
{
    CheckIfGrounded ();
}

void OnCollisionExit2D(Collision2D collider)
{
    Grounded = false;
}

private void CheckIfGrounded()
{
    RaycastHit2D[] hits;

    //We raycast down 1 pixel from this position to check for a collider
    Vector2 positionToCheck = transform.position;
    hits = Physics2D.RaycastAll (positionToCheck, new Vector2 (0, -1), 0.01f);

    //if a collider was hit, we are grounded
    if (hits.Length > 0) {
        Grounded = true;
    }
}
\$\endgroup\$
0
\$\begingroup\$

Use the following script it will work well...

Animator anim;
Rigidbody2D rigid;
bool facingRight = true;
bool canJump = true;
public Transform startpos, endpos;
public LayerMask groundLayer;

void Start()
{
    rigid = gameObject.GetComponent<Rigidbody2D>();
    anim = gameObject.GetComponent<Animator>();
}
void Update()
{
    float move = Input.GetAxisRaw("Horizontal");
    anim.SetFloat("speed", Mathf.Abs(move));
    rigid.velocity = new Vector2(move * 5f, rigid.velocity.y);


    RaycastHit2D hit = Physics2D.Linecast(startpos.position, endpos.position, groundLayer.value);

    if (hit.collider != null)
    {
        canJump = true;
        anim.SetBool("jump", false);
    }
    if (Input.GetKeyDown(KeyCode.Space) && canJump == true)
    {
        anim.SetBool("jump", true);
        rigid.velocity = Vector2.up * 10f;
        canJump = false;
    }

    if (facingRight && move < 0)
    {
        facingRight = false;
        transform.rotation = Quaternion.Euler(transform.rotation.x, 180, transform.rotation.z);
    }
    else if (!facingRight && move > 0)
    {
        facingRight = true;
        transform.rotation = Quaternion.Euler(transform.rotation.x, 0, transform.rotation.z);
    }

}

Place 'startpos' empty object on the center of the character and 'endpos' empty object on the bottom of the character.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.