It seems to work ok, but for some reason not 100% of the time. The button might need to be pressed once or several times to get the character to jump. I have:
Disabled the gravity on the rigidbody (rb) and froze the rotation. All other settings are default
The gravity is 9 and the jumpSpeed is 7
I’ve switched buttons/keys in case there was an input issue
I’ve verified that the controller is indeed grounded
I need a second pair of eyes here. Why is this not working 100% of the time?
Hmmm, I could be wrong, but try printing out your rb.velocity.
momentum -= transform.up * gravity * Time.deltaTime;
Will decrease your momentum more and more the longer your character is in the air. It will always be negative on the Y-axis because of that reason.
velocity += momentum;
Will lower your velocity by your momentum ALWAYS. Thus, I believe, that when the character hits the ground, the velocity on the Y-axis is still negative due to it never resetting.
If I’m correct, once you Debug.Log(rb.velocity) you should see a negative number on your Y-axis. To fix it, simply set the Y velocity of the rb to 0 once the player is grounded:
This would cause you to have to push the jump button faster to “over take” the downward force, so it might be the issue as well. If you let this sit for awhile you probably couldn’t press jump fast enough to even make it jump at all, and if it gets a fast enough downward force than it would start to push through the ground.
Let us know if this is the issue.
I would use built in gravity and then use rigidBody.AddForce() to jump myself to avoid such issues.
sensor radius is .3, collider is 2 units by .5, layermask is everything, and the offset is .01f to get it just a smidge above the ground. The controller is pretty much sitting on the spherecast.
Thanks, that isn’t the issue. I also want precise control over the character. I’m overriding the rb’s velocity during movement, so any AddForce would be zeroed out or overwritten.
SphereCast for something like this is over kill, its more processing than OverlapSphere when the overlap will do the same thing. Use SphereCast like a RayCast that needs to be wider than a Ray.
Should use layermasks to stop it from registering on other colliders. I usually setup a Ground layer and have it only look for collisions with that.
Other than that I have no idea what could be wrong. Debug.Log IsGrounded to make sure its registering the ground. Debug.Log everything really each step of the way to see what goes on, or use the debugger in VS and step through the code and have a look.
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
bool grounded = IsGrounded();
if (grounded && Input.GetButtonDown("Jump"))
{
rBody.AddForce(Vector3.up * jumpForce);
}
rBody.velocity = new Vector3(move.x, rBody.velocity.y, move.z);