Search Unity

Player Movement Freezes

Discussion in 'Scripting' started by techtide, Feb 17, 2016.

  1. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Hello all,
    I have created a player controller script like this:

    Code (csharp):
    1.  
    2.     using UnityEngine;
    3.     using System.Collections;
    4.  
    5.     public class PlayerController : MonoBehaviour {
    6.  
    7.         public float speed;
    8.         public Rigidbody rb;
    9.         public Animator anim;
    10.         public float jumpPower;
    11.         private bool grounded;
    12.         private float distToGround;
    13.         public float hits;
    14.  
    15.  
    16.         // Use this for initialization
    17.         void Start () {
    18.             rb = GetComponent<Rigidbody>();
    19.             anim = GetComponent<Animator>();
    20.  
    21.         }
    22.         void OnCollisionStay(Collision collisionInfo)
    23.         {
    24.             grounded = true;
    25.         }
    26.  
    27.         void OnCollisionExit(Collision collisionInfo)
    28.         {
    29.             grounded = false;
    30.         }
    31.         // Update is called once per frame
    32.         void Update () {
    33.          
    34.  
    35.             float moveHorizontal = Input.GetAxis("Horizontal");
    36.             float moveZ = Input.GetAxis("Vertical");
    37.             rb.velocity = new Vector3(moveHorizontal *speed, rb.velocity.y, moveZ*speed);
    38.  
    39.             if(Input.GetKeyDown(KeyCode.Space) && grounded == true)
    40.             {
    41.                 Jump();
    42.             }
    43.         }
    44.  
    45.         void Jump()
    46.         {
    47.             rb.AddForce(Vector3.up * jumpPower);
    48.            // animation.Play("jump_pose");
    49.         }
    50.         void FixedUpdate()
    51.         {
    52.             //
    53.         }
    54.  
    55.     }
    56.  

    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: https://gyazo.com/1b516af1ae6b493297139a7ad9ca61f1

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

    Thanks,

    8Development
     
    Last edited: Feb 19, 2016
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Put your codes into [CODE][/CODE] tags
     
  3. joewode

    joewode

    Joined:
    Dec 3, 2014
    Posts:
    35
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour {
    5.  
    6. public float speed;
    7. public Rigidbody rb;
    8. public Animator anim;
    9. public float jumpPower;
    10. private bool grounded;
    11. private float distToGround;
    12. public float hits;
    13.  
    14.  
    15. // Use this for initialization
    16. void Start () {
    17. rb = GetComponent<Rigidbody>();
    18. anim = GetComponent<Animator>();
    19.  
    20. }
    21. void OnCollisionStay(Collision collisionInfo)
    22. {
    23. grounded = true;
    24. }
    25.  
    26. void OnCollisionExit(Collision collisionInfo)
    27. {
    28. grounded = false;
    29. }
    30. // Update is called once per frame
    31. void Update () {
    32.  
    33. float moveHorizontal = Input.GetAxis("Horizontal");
    34. float moveZ = Input.GetAxis("Vertical");
    35.  
    36. if(Input.GetKeyDown(KeyCode.Space) && grounded == true)
    37. {
    38. Jump();
    39. }
    40. }
    41.  
    42. void Jump()
    43. {
    44. rb.AddForce(Vector3.up * jumpPower);
    45. // animation.Play("jump_pose");
    46. }
    47. void FixedUpdate()
    48. {
    49. rb.AddForce(moveHorizontal * speed, rb.velocity.y, moveZ * speed);
    50. }
    51.  
    52. }
    try using addforce instead of velocity.
     
    Last edited: Feb 17, 2016
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    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.
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class PlayerController : MonoBehaviour {
    6.     public Animator anim;
    7.     public float speed = 8;
    8.     public float jumpPower = 7;
    9.     public float hits;
    10.    
    11.     private bool grounded = false;
    12.     private float distToGround;
    13.     private Rigidbody rb;
    14.    
    15.  
    16.  
    17.     // Use this for initialization
    18.     void Start () {
    19.         rb = GetComponent<Rigidbody>();
    20.         anim = GetComponent<Animator>();
    21.     }
    22.     // Update is called once per frame
    23.     void Update () {
    24.         if(rb == null) return;
    25.         // gather movement keys
    26.         float moveh = Input.GetAxis("Horizontal");
    27.         float movev = Input.GetAxis("Vertical");
    28.         // create a vector from those keys
    29.         Vector3 newVelocity = new Vector3(moveh * speed, 0, movev * speed);
    30.        
    31.         // use the camera to transform the rotation of the velocity
    32.         Transform camera = Camera.main.transform;
    33.         Vector3 lookAt = camera.position + camera.forward;
    34.         lookAt.y = camera.y;
    35.         camera.LookAt(lookAt);
    36.         newVelocity = camera.TransformDirection(newVelocity);
    37.         // reset the camera to look at the player
    38.         camera.LookAt(transform);
    39.         // assign the y from the current velocity
    40.         newVelocity.y = rb.velocity.y;
    41.        
    42.         // if we are grounded, lerp the velocity towards the new one at a fast rate
    43.         // also, if we just pressed the jump key, jump
    44.         if(grounded){
    45.             newVelocity = Vector3.Lerp(rb.velocity, newVelocity, 5 * Time.deltaTime);
    46.             if(Input.GetKeyDown(KeyCode.Space)){
    47.                 newVelocity = new Vector3(newVelocity.x, jumpPower, newVelocity.y);
    48.             }
    49.         } else {
    50.             // if we are not grounded, we lerp the velocity towards the new one at a slow rate
    51.             newVelocity = Vector3.Lerp(rb.velocity, newVelocity, Time.deltaTime);
    52.         }
    53.         // set the velocity back onto the object.
    54.         rb.velocity = newVelocity;
    55.        
    56.         // update our grounded variable if we can spherecast to the ground.
    57.         RaycastHit hit;
    58.         Ray ray = new Ray(transform.position, Vector3.down);
    59.         grounded = Physics.SphereCast(ray, 0.5f, 0.55f);
    60.     }
    61.  
    62. }
    63.  
     
  5. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    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
     
  6. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    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.
     
  7. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    @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
     
  8. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    so.... the jump height... which is not specific by the way, can jump higher, if you are on the ground longer?

    Code (csharp):
    1.  
    2. newVelocity = new Vector3(newVelocity.x, jumpPower, newVelocity.y);
    3.  
    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.
     
  9. techtide

    techtide

    Joined:
    Aug 22, 2015
    Posts:
    38
    Thank you guys so much for your help. I found out all I really had to do was change the velocity line.
    Code (csharp):
    1.  
    2.         transform.position += new Vector3(input_x , 0f, input_y ).normalized * speed * Time.deltaTime;
    3.  
    Thanks,
    8Development