Everything worked fine until I added acceleration on the x axis..now when I try to jump it just lifts up very little from the ground in a weird way and then it slowly sinks down like having 0 gravity. Here is the code I'm using:

public class PlayerMovement : MonoBehaviour {

    public float baseSpeed = 10f;
    public float maxSpeed = 10f;
    public float timeFromZeroToMax = 10f;
    public float jumpSpeed = 10f;
    public Collider coll;

    float accelRatePerSecond;
    float forwardVelocity;
    Rigidbody rb;

    void Awake () {
        rb = GetComponent<Rigidbody>();
        coll = GetComponent<Collider>();

        accelRatePerSecond = maxSpeed / timeFromZeroToMax;
        forwardVelocity = 0f;

    void FixedUpdate() {

        transform.Translate(transform.right * baseSpeed * Time.deltaTime);
        forwardVelocity += accelRatePerSecond * Time.deltaTime;
        forwardVelocity = Mathf.Min(forwardVelocity, maxSpeed);

        if (isGrounded() && Input.GetKeyDown("w"))
            rb.AddForce(transform.up * jumpSpeed * Time.deltaTime, ForceMode.Impulse);

    void LateUpdate()
        rb.velocity = transform.right * forwardVelocity;
    bool isGrounded()
        return Physics.Raycast(transform.position, Vector3.down, coll.bounds.extents.y + 0.1f);

Let's just walk through one frame step by step as an exercise.

First, FixedUpdate:

  • We translate the object rightward by our baseSpeed (no effect on velocity)

  • We increase the forwardVelocity by accelRatePerSecond but don't yet use it. For our purposes let's say we were already at maxSpeed since the previous frame to keep the numbers simple.

  • We jump by adding an upward force.

    Let's say the rigidbody velocity is now (10, 5, 0)

Then, in LateUpdate:

  • We set velocity to forwardVelocity * transform.right

    Our rigidbody velocity is now (10, 0, 0) <-- our y component is gone now.

So what happened to our upward velocity from the jump, or downward velocity from the fall? We told the physics engine to throw it out and use only the forwardVelocity * transform.right, stomping whatever other velocity it might have accumulated earlier in the frame. This almost certainly not what you want to do.

Instead, you might want to consider applying your velocity solely to the x component while keeping the y component unchanged, or treating this step as an acceleration/deceleration to a target speed along the ground direction when isGrounded is true (this would let the object get an assist from gravity when going downhill, for example).

There are a number of other physics mistakes in this code:

  • As a general rule, don't use both Rigidbody physics and Transform position/translation/rotation on the same object. This periodically rips control away from the physics engine and can cause excess processing for the physics to catch up to this out-of-band modification (from the physics engine's point of view, the object just teleported), produce implausible reactions from other physics objects, and will disable interpolation/extrapolation if you're using it.

    Instead, commit to one or the other. Either steer your object using the Rigidbody exclusively (using velocity, AddForce, or MovePosition), or skip the Rigidbody and go pure Transform manipulation if you don't need the physics engine's collision checks.

  • Applying Time.deltaTime to an Impulse is not meaningful. An impulse represents an instantaneous change to the object's motion, not an influence that is sustained over a duration. And you don't want the intensity of the player's jump to vary based on the fixed timestep you choose.

    Given that you're passing a speed as an input here, it looks like you want rb.AddForce(transformn.up * jumpSpeed, ForceMode.velocityChange) instead

  • Applying continuous Physics effects (not instantaneous reactions) in LateUpdate rather than FixedUpdate can mean they trigger with an uneven frequency relative to the physics step. You might sometimes go 0, 1, 2, or 3 physics steps integrating the motion of the object between these velocity updates, which can give your motion an uneven and stuttering look. Generally, any continuous physics effects should go in FixedUpdate to ensure they're processed in lockstep with the other physics simulation.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.