Why my ball doesn't jump

Does someone know why my ball doesn’t want to jump.

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

public class PlayerController : MonoBehaviour {

    public float jump;
    public float speed;

    // Initializing the rigidbody attached
    private Rigidbody rb;
    private SphereCollider playerCollider;

    void Components()
    {
        // Declaring the rigidbody component
        rb = GetComponent<Rigidbody> ();
        playerCollider = GetComponent<SphereCollider> ();
    }

    void Start()
    {
        Components ();
    }

    bool IsGrounded()
    {
        // Detecting ground with raycast
        return Physics.Raycast(rb.transform.position + playerCollider.radius * Vector3.down, Vector3.down, 0.1f);
    }

    void Jump()
    {
        if (Input.GetKeyDown ("space") && IsGrounded ()) {
            rb.AddForce (new Vector3 (0, jump, 0));
            print ("grounded");
        }
    }

    void BallControls()
    {
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        rb.AddTorque (new Vector3 (moveHorizontal, 0, moveVertical) * speed * Time.deltaTime);
    }

    void FixedUpdate()
    {
        IsGrounded ();
        Jump ();
        BallControls ();
    }
}

First, you shouldn’t use Input.GetKeyDown() in FixedUpdate. It needs to be moved to an Update function.

Second, your call to IsGrounded() in FixedUpdate doesn’t actually do anything. The function returns a boolean which tells whether your thing is grounded but in FixedUpdate(), you never actually use the returned boolean. You do call IsGrounded() in Jump(), but since your Jump function requires the GetKeyDown function and occurs in FixedUpdate(), it probably won’t work.

I’d suggest using flags. Have a “jumpTriggered” flag and an “isGrounded” flag. In Update, you set the jumpTriggered flag by checking whether the space key is pressed and whether your isGrounded flag is true, and in FixedUpdate, you set the isGrounded flag by doing your raycast (call “IsGrounded”). Then in FixedUpdate, if jumpTriggered is true, you call your jump function and set both of those flags to false. You’ll need another check to set the isGrounded state back to true when you land.

Re the above logic, you might have to debug it a little, this was off the top of my head.

Here’s a thread that is relevant:

A few things to look at:

You should never use Input.GetKeyDown in FixedUpdate, because it is only true on the single frame the key was pressed, but there is no guarantee that FixedUpdate will be called during that frame. So at best it will only work intermittently. You should take your input in Update. Generally it is good practice to separate the taking of input and reacting to input anyway. If you insist on checking input in FixedUpdate, try Input.GetKey instead, as it returns true on all frames the key is held down so should be more reliable to use in FixedUpdate.

Your IsGrounded() method might be returning false. You should add debugging to it to determine if that is the case. Also I don’t understand why you call it at the start of FixedUpdate, and then immediately call it a second time inside the Jump() method. You should just call it once.

The default ForceMode for RigidBody.AddForce is ForceMode.Force, which is intended to be applied continuously over time, such as a rocket booster effect. From the way you are using AddForce I think ForceMode.Impulse would be more appropriate.

Whatever value you have set for “jump” may be too low to overcome gravity, drag, etc, for whatever the mass of the object is.

Why grounded is directly true? now I have put notgrounded but that doesn’t make any sense. I have putted forcemode into it and removed jump from fixedupdate.

void Jump()
    {
        if (Input.GetKeyDown ("space") && !IsGrounded ())
        {
            rb.AddForce (new Vector3 (0, jump, 0), ForceMode.Impulse);
            Debug.Log (IsGrounded());
            print ("grounded");
        }
    }

Don’t you want to only allow a jump when IsGrounded() is true though? The way you just changed it the ball can only jump if it had already jumped or otherwise was already off the ground. Doesn’t make any sense.

With the ! mark it can jump, without it cannot.

Did you add debugging to IsGrounded() as I suggested to see if it is even working as you expect it to? I am guessing you did not. It is probably returning false when you expect it to return true.

Nothing gets triggered inside the if statement of jump. But I did put a debug inside the update and yes it returns false. Shouldn’t it return true? Because my ball is grounded so.

void Jump()
    {
        if (Input.GetKeyDown ("space") && IsGrounded ())
        {
            rb.AddForce (new Vector3 (0, jump, 0), ForceMode.Impulse);
            Debug.Log (IsGrounded());
            print ("grounded");
        }
    }

void Update()
    {
        Debug.Log (IsGrounded());
        Jump ();
        BallControls ();
    }

Change IsGrounded() to something like below. If the ball is on the ground and IsGrounded() is false then you need to figure out what is going wrong with your raycast code.

    bool IsGrounded()
    {
        // Detecting ground with raycast
        bool returnValue = Physics.Raycast(rb.transform.position + playerCollider.radius * Vector3.down, Vector3.down, 0.1f);
        Debug.Log("IsGrounded() == " + returnValue.ToString();
        return returnValue;
    }

I don’t know man I changed to addition sign to minus and extended the vector3. It shows true now, but even with the if statement I check if !IsGrounded and it still shows true when I’m in the air.

bool IsGrounded()
    {
        // Detecting ground with raycast
        bool returnValue = Physics.Raycast(rb.transform.position - playerCollider.radius * Vector3.down, Vector3.down, 0.5f);
        Debug.Log("IsGrounded() == " + returnValue.ToString());
        return returnValue;
        // Debug.DrawRay (returnValue, Color.green);
    }

    void Jump()
    {
        if (Input.GetKeyDown ("space") && IsGrounded ()) {
            rb.AddForce (new Vector3 (0, jump, 0), ForceMode.Impulse);
            Debug.Log (IsGrounded ());
            print ("grounded");
        }
        else if(Input.GetKeyDown ("space") && !IsGrounded ())
        {
            rb.AddForce (new Vector3 (0, 0, 0), ForceMode.Impulse);
            Debug.Log (IsGrounded ());
        }
    }

Ummm, isn’t !IsGrounded() being true in the air what you want? You know what the ! does right?

Fixed it with a simple velocity check.

void Jump()
    {
        if (Input.GetKeyDown ("space") && rb.velocity.y == 0 )
        {
            rb.AddForce (new Vector3 (0, jump, 0), ForceMode.Impulse);
        }
    }

Your velocity will also be zero at the peak of a jump, so I don’t think that’s the solution you’re after.

You may want to check your raycast using DrawRay. Also, instead of using a local member, returnedValue in IsGrounded, you should make it a public member that you can watch in the inspector. Often that’s a good way to debug these kinds of things rather than putting debug logs everywhere-- at least that’s where I’d start.

I know but it works for now, maybe later I will try to make the code better.