Player Movement Freezes

Hello all,
I have created a player controller script like this:

    using UnityEngine;
    using System.Collections;
  
    public class PlayerController : MonoBehaviour {
  
        public float speed;
        public Rigidbody rb;
        public Animator anim;
        public float jumpPower;
        private bool grounded;
        private float distToGround;
        public float hits;
  
  
        // Use this for initialization
        void Start () {
            rb = GetComponent<Rigidbody>();
            anim = GetComponent<Animator>();
  
        }
        void OnCollisionStay(Collision collisionInfo)
        {
            grounded = true;
        }
  
        void OnCollisionExit(Collision collisionInfo)
        {
            grounded = false;
        }
        // Update is called once per frame
        void Update () {
          
  
            float moveHorizontal = Input.GetAxis("Horizontal");
            float moveZ = Input.GetAxis("Vertical");
            rb.velocity = new Vector3(moveHorizontal *speed, rb.velocity.y, moveZ*speed);
  
            if(Input.GetKeyDown(KeyCode.Space) && grounded == true)
            {
                Jump();
            }
        }
  
        void Jump()
        {
            rb.AddForce(Vector3.up * jumpPower);
           // animation.Play("jump_pose");
        }
        void FixedUpdate()
        {
            //
        }
  
    }

This script, however, does not seem to be working. It usually ends up freezing the player where you cannot move the player at all with any keys. This is demonstrated here: https://embed.gyazo.com/768346efa3444041f574b65912f852c2.gif
It is also demonstrated here showing the movement before it: Screen capture - 1b516af1ae6b493297139a7ad9ca61f1 - Gyazo

Could you please advise me on how to fix this? I would appreciate any help.

Thanks,

8Development

Put your codes into [PLAIN]``[/PLAIN] tags

using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour {

public float speed;
public Rigidbody rb;
public Animator anim;
public float jumpPower;
private bool grounded;
private float distToGround;
public float hits;


// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
anim = GetComponent<Animator>();

}
void OnCollisionStay(Collision collisionInfo)
{
grounded = true;
}

void OnCollisionExit(Collision collisionInfo)
{
grounded = false;
}
// Update is called once per frame
void Update () {

float moveHorizontal = Input.GetAxis("Horizontal");
float moveZ = Input.GetAxis("Vertical");

if(Input.GetKeyDown(KeyCode.Space) && grounded == true)
{
Jump();
}
}

void Jump()
{
rb.AddForce(Vector3.up * jumpPower);
// animation.Play("jump_pose");
}
void FixedUpdate()
{
rb.AddForce(moveHorizontal * speed, rb.velocity.y, moveZ * speed);
}

}

try using addforce instead of velocity.

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.

Thank you guys so much for your help. I found out all I really had to do was change the velocity line.

        transform.position += new Vector3(input_x , 0f, input_y ).normalized * speed * Time.deltaTime;

Thanks,
8Development