0
\$\begingroup\$

There is this thing. I have Coded to check if my character is grounded. And it works fine. But problem is that I have added a code to jump. When my character jumps while checking my character is grounded it works but when the character finishes jumping and tries to return to ground boolean isgrounded changes to true even if it isn't grounded. Here is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class pScript : MonoBehaviour {
    public Rigidbody2D rb;
    [SerializeField]
    public Transform[] Points;
    [SerializeField]
    public float radius;
    [SerializeField]
    public LayerMask layer;
    public bool jump;
    public bool isgrounded = false;
    [SerializeField]
    public float MoveSpeed;
    [SerializeField ]
    public float jumpHigh;
    public bool facingRight;
    public float localScale;
    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody2D> ();

    }

    // Update is called once per frame
    void Update () {
        isgrounded = isGrounded ();
        float horizontal = Input.GetAxis ("Horizontal");
        rb.velocity = new Vector2 (horizontal * MoveSpeed, rb.velocity.y);
        if (Input.GetKeyDown (KeyCode.Space)) {
            jump = true;

        }
        if (isgrounded && jump == true) {
            isgrounded = false;
            rb.velocity = new Vector2 (0, jumpHigh);

        }

        if (isgrounded == false) {
            jump = false;
        }






    }
    private bool isGrounded(){

        if (rb.velocity.y <= 0) {
            foreach (Transform points in Points) {
                Collider2D[] collider = Physics2D.OverlapCircleAll (points.position, radius, layer);
                for (int i = 0; i < collider.Length; i++) {
                    if (collider [i].gameObject != gameObject) {
                        return true;
                    }

                }

            }

        }return false;


    }
}
\$\endgroup\$
  • \$\begingroup\$ That's an unusual grounded check function. Does your character have a particularly unconventional shape or construction that makes this complex approach necessary over simpler options? If so, can you walk us through how this character is set up? \$\endgroup\$ – DMGregory Nov 20 '18 at 14:31
  • \$\begingroup\$ To remind you, I am a noob and had been in this game development for only around 3-4 months. I have been watching tutorial in youtube channel named "Inscope Studios." To make you sure, I haven't quite got some of the code of the isgrounded function. The real thing is, I have a character and on his foot , there are three empty objects. This function checks if those three empty object is colliding0-= \$\endgroup\$ – Sabin Pyakurel Nov 20 '18 at 14:38
  • 1
    \$\begingroup\$ Can you show us how your character and their feet are set up? This sounds suspiciously like overkill for your needs. Most games get by with a single trigger or spherecast or a pair of raycasts. \$\endgroup\$ – DMGregory Nov 20 '18 at 14:41
  • 1
    \$\begingroup\$ Can you also edit your question to be kinda more ... descriptive? Right now it literally says that the character jumps when you try to jump, which doesn't sound like a problem that needs a solution? \$\endgroup\$ – TomTsagk Nov 20 '18 at 17:04
0
\$\begingroup\$

While the ground is within the radius of the circle, your character's "feet" might not in contact with the ground.

Let us suppose that our ground is any point where y <= 0. Let us also suppose that the center point for our collision checking circle is at (0, 10) with a radius of 15. The point (0, -5) is within both our circle and the ground resulting in a collision. Suppose our units are meters, would you say that something 10 meters above the ground is grounded? Suppose our units are in nanometers, would you say that something 10 nanometers above the ground is grounded? That is a decision you must make.

One way to address this problem is to set the radius in the call to Physics2D.OverlapCircleAll small enough that a collision is effictively checking equality. In our previous example we could reduce the radius of the circle to 1 meter, but again we must ask the question, for our purposes is 1 meter above the ground on the ground.

Another option is to add a second, hard, check ensuring that the point is within the bounds of the collider, i.e. foreach collider in collisions { if collider.x_min <= point.x <= collider.x_max && collider.y_min <= point.y <= collider.y_max { return true; } } Likely you will want a combination of the two because reducing the radius reduces the number of hard checks you must make.

On a side note, it may also be worth refactoring to increase readability. void Update() { float horizontal = Input.GetAxis ("Horizontal"); rb.velocity = new Vector2 (horizontal * MoveSpeed, rb.velocity.y); if (Input.GetKeyDown (KeyCode.Space)) { if (isGrounded()) { // adjust velocity } } }

It is also worth noting that currently a character with a y velocity of 0 is not considered grounded and will be unable to jump

| improve this answer | |
\$\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.