Jumpy movement with 2d physics

I really didn’t want to post this, the shear volume of topics about jumpy movement is insane, but I’m completely stumped and pretty frustrated!

I have a very simple 2d scene, with a player (rigidbody2D) moving based on physics2d, on x at an increasing speed, and y in a wave-like motion using gravity and then turning gravity off and AddForce to move upwards, then turning gravity back on to move back down. (imagine a fish jumping in and out of water).

The camera is following the fish, using simply transform.position and the scenery is all very slightly jumpy/stuttering. It’s subtle but very noticeable.

I’ve tried literally EVERY solution others have had success with but have had no luck. I think I’ve done something wrong in my movement scripts but I don’t know what.

Here is what I’ve already tried:

  • Interpolate on player rigidbody - This makes the problem worse

  • vsync off - again, this makes it worse

  • using SmoothDamp on the camera instead of transform.position - This makes the scenery perfectly smooth, but the player is then the jumpy object, and about 4x as noticeable.

  • Settings a constant velocity on the player instead of AddForce to gradually incrase - I thought it could be the dynamic speed causing issues, but no, I still get problems at a constant speed.

  • Setting a fixed frame rate - no difference

  • Setting the camera’s movement in FixedUpdate instead of Update

  • Setting the camera movement in LateUpdate instead of Update

  • Setting the player velocity/addForce in Update instead of FixedUpdate

The player is a gameobject containing a few sprites and the camera should follow it (with a bit of offset). The rest of the objects in the scene are completely static (for now, eventually it will be animated).

Here are my movement scripts:

Player

void FixedUpdate()
{
    if ( running )
    {
        if ( rigidbody2D.velocity.x < targetVelocityX )
        {
            rigidbody2D.AddForce( Vector2.right * runForce );
        } else {
            rigidbody2D.velocity = new Vector2( targetVelocityX, 0 );
        }

        if ( rigidbody2D.velocity.x > speedToJump ) {
            // jump
            rigidbody2D.velocity = new Vector2( rigidbody2D.velocity.x, maxVelocity );
            rigidbody2D.gravityScale = 1;
            running = false;
        }

    }

    // limit y velocity
    if ( rigidbody2D.velocity.y > maxVelocity ) rigidbody2D.velocity = new Vector2( rigidbody2D.velocity.x, maxVelocity );
   //limit x
   if ( rigidbody2D.velocity.x > targetVelocityX ) rigidbody2D.velocity = newVector2( targetVelocityX, rigidbody2D.velocity.y );
}

Camera

void Update()
{
    transform.position = new Vector3( player.transform.position.x + offsetX, player.transform.position.y, player.transform.position.z );
}

Water

void OnTriggerStay2D(Collider2D collider)
{
    if ( collider.tag == "Water" )
    {
        playerScript.inWater = true;
        rigidbody2D.gravityScale = 0;

        rigidbody2D.AddForce( new Vector2( 2 , ( rigidbody2D.mass * buoyancy ) ) );
    }
}


void OnTriggerExit2D(Collider2D collider)
{
    if ( collider.tag == "Water" ) {
        playerScript.inWater = false;
        rigidbody2D.gravityScale = 1;

    }
}

Thanks! :slight_smile:

If you’re having issues, the first thing I would do is avoid modifying velocity directly. Instead, I would just add a force every fixed frame to get the relative speed you’d like. See if that fixes your issue.

Thanks Mike! Ok I’ll give it go taking out all instances where I adjust velocity directly. So, for example, on line 14 of the player script where I make the player jump at a defined speed, I’ll need to figure out what force I need to add to achieve that speed instead of setting the y velocity directly to it?

I’ve replaced all instances of “rigidbody2d.velocity =” with “rigidbody2d.AddForce()” and it doesn’t seem to have made any difference.

Sorry about the delay (the forums don’t email me when there is a reply). Don’t change the camera to the player immediately, try using Lerp instead.

transform.position = Vector3.Lerp(target.position, transform.position, 5 * Time.deltaTime); <the 5 is arbitrary>

Hey Luke, I am having the exact same issue as you, have you since solved the problem, maybe we can chat and I can show you the issue I’m having?

https://forum.unity.com/threads/2d-movement-stutter-w-basic-project.312561/#post-8407269