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!