Search Unity

Gravity not Affecting Player Character using transform.Translate

Discussion in 'Scripting' started by AnimusRex, May 10, 2019.

  1. AnimusRex

    AnimusRex

    Joined:
    Apr 26, 2019
    Posts:
    67
    Hi all,

    I've recently implemented a different movement type for my player object, but it's caused gravity to stop working and I'm not sure why

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         float moveHorizontal = Input.GetAxisRaw("Horizontal");
    4.         float moveVertical = Input.GetAxisRaw("Vertical");
    5.  
    6.         Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
    7.         transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(movement), 0.2F);
    8.  
    9.         transform.Translate(movement * moveSpeed * Time.deltaTime, Space.World);
    10.  
    11.         //moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale * Time.deltaTime);
    12.  
    13.     }
    That's the code I'm using; I'm assuming it's translating every frame without respect to gravity? But I'm not really sure where to put my older gravity line.

    Any insight would be great.

    Cheers.
     
  2. DryerLint

    DryerLint

    Joined:
    Feb 7, 2016
    Posts:
    68
    Instead of
    transform.Translate(movement * moveSpeed * Time.deltaTime, Space.World);

    Try
    transform.Translate((movement * moveSpeed + Physics.gravity * gravityScale) * Time.deltaTime, Space.World);


    Also, in almost all cases you ought to use the RigidBody component to manage the movement of physical objects. It applies gravity automatically (i.e., you needn't add it into translation operations).
     
  3. AnimusRex

    AnimusRex

    Joined:
    Apr 26, 2019
    Posts:
    67
    Hey, thanks for the help.

    The player char has both a rigidbody and a character controller, the Rigidbody is set to kinematic and use gravity, and yet with your code he falls through anything he should be colliding with
     
  4. DryerLint

    DryerLint

    Joined:
    Feb 7, 2016
    Posts:
    68
    Ahh, ok, I think I see your problem.

    You've got both a character controller and a Rigidbody, yet neither are being used. You're directly accessing your object's Transform to move it, which applies position changes irrespective of physics or collision.

    As far as I understand it, the character controller component doesn't even use the Rigidbody, and Rigidbody can get along fine without a character controller. First, decide whether you want to use the character controller or the Rigidbody to move your object. If you want to use the Rigidbody, which uses Unity's physics system (character controller does not), then make sure you disable 'kinematic' (despite what the word 'kinematic' might imply, it actually effectively disables the Rigidbody). Rigidbody automatically applies gravity if the 'use gravity' option is set, you don't need to manually calculate it.

    Character controller movement:
    Code (CSharp):
    1. movement *= moveSpeed;
    2. movement -= Physics.gravity * Time.deltaTime;
    3. GetComponent<CharacterController>().Move(movement * Time.deltaTime);
    Rigidbody controller movement (no gravity calculation needed):
    GetComponent<Rigidbody>().MovePosition(movement * moveSpeed * Time.deltaTime);
     
  5. AnimusRex

    AnimusRex

    Joined:
    Apr 26, 2019
    Posts:
    67
    Hey, I appreciate the feedback. I'm not super familiar with Unity, I've turned off the character controller and removed references to it in my script.

    I've implemented jumping, but all of my characters movements have a strange jerking quality... Perhaps I'm missing a deltaTime somewhere?

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         float moveHorizontal = Input.GetAxis("Horizontal");
    4.         float moveVertical = Input.GetAxis("Vertical");
    5.  
    6.         Vector3 jump = new Vector3(0, jumpForce, 0);
    7.         Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
    8.  
    9.         if (moveHorizontal + moveVertical != 0)
    10.         {
    11.             transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(movement), 0.2F);
    12.         }
    13.  
    14.         if (Input.GetButton("Jump"))
    15.         {
    16.             movement = movement + jump;
    17.         }
    18.  
    19.         transform.Translate((movement * moveSpeed) * Time.deltaTime, Space.World);
    20.  
    21.     }
    22. }
    EDIT: Changing to Time.smoothDeltaTime fixed it for the most part, but I'm still curious why it would be happening, if you know.
     
    Last edited: May 10, 2019
  6. DryerLint

    DryerLint

    Joined:
    Feb 7, 2016
    Posts:
    68
    Sometimes jerky animation is due to a disparity between physics objects updates (handled internally by the engine) and objects that are updated using Update(). Try using FixedUpdate() and see if the jerky animation still remains (remember to change smoothDeltaTime back to deltaTime).
     
  7. AnimusRex

    AnimusRex

    Joined:
    Apr 26, 2019
    Posts:
    67
    That does appear to have fixed it; I'm still having collision issues likely for the same reason. For example if the character walks towards the underside of a ramp, he can push himself info the floor.. The capsule collider I have on the character seems to work in general for the collision detection until it comes into conflict with the Update method.