well, from the looks of it, you are using onCollision events to handle your grounded method, which is probably not the best way to do it.
You can use velocity, as that is a convenient way to control the actual rigidbody.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public Animator anim;
public float speed = 8;
public float jumpPower = 7;
public float hits;
private bool grounded = false;
private float distToGround;
private Rigidbody rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
if(rb == null) return;
// gather movement keys
float moveh = Input.GetAxis("Horizontal");
float movev = Input.GetAxis("Vertical");
// create a vector from those keys
Vector3 newVelocity = new Vector3(moveh * speed, 0, movev * speed);
// use the camera to transform the rotation of the velocity
Transform camera = Camera.main.transform;
Vector3 lookAt = camera.position + camera.forward;
lookAt.y = camera.y;
camera.LookAt(lookAt);
newVelocity = camera.TransformDirection(newVelocity);
// reset the camera to look at the player
camera.LookAt(transform);
// assign the y from the current velocity
newVelocity.y = rb.velocity.y;
// if we are grounded, lerp the velocity towards the new one at a fast rate
// also, if we just pressed the jump key, jump
if(grounded){
newVelocity = Vector3.Lerp(rb.velocity, newVelocity, 5 * Time.deltaTime);
if(Input.GetKeyDown(KeyCode.Space)){
newVelocity = new Vector3(newVelocity.x, jumpPower, newVelocity.y);
}
} else {
// if we are not grounded, we lerp the velocity towards the new one at a slow rate
newVelocity = Vector3.Lerp(rb.velocity, newVelocity, Time.deltaTime);
}
// set the velocity back onto the object.
rb.velocity = newVelocity;
// update our grounded variable if we can spherecast to the ground.
RaycastHit hit;
Ray ray = new Ray(transform.position, Vector3.down);
grounded = Physics.SphereCast(ray, 0.5f, 0.55f);
}
}
Velocity may not be that convenient, because if you jump, there is always a maximum height, and the velocity there is 0 as well and if you have a good timing, you could just jump forever
run that code and tell me if you can jump forever… you can only jump when grounded is true… and grounded is only true if you can spherecast to the ground below you.
@bigmisterb Ohh, you were talking about setting the velocity, well sorry. Your system has a huge bug. The jump height will change based on the frames the player was in the ground.
Edit: not when you’re working with velocity itself, but the docs don’t recommend that
so… the jump height… which is not specific by the way, can jump higher, if you are on the ground longer?
newVelocity = new Vector3(newVelocity.x, jumpPower, newVelocity.y);
This line sets the velocity to jumpPower… no more, no less. If you spend 100 frames on the ground, then press the jump key you are going to give yourself jumpPower velocity. AddForce would do exactly what you are describing, not setting the velocity directly.
Please test the code before you start pointing flaws and bugs. I have used this same type of code many times and it works great every time.