Quick answer: You are reading the mouse position in Update but moving the body in FixedUpdate. Sample input in Update, cache it, then call Rigidbody2D.MovePosition from FixedUpdate, and set Interpolation to Interpolate on the Rigidbody2D component.
You wire up a top-down character or a custom cursor to follow the mouse. It works, but the sprite buzzes back and forth like it has a tremor. The faster you move the cursor, the worse the shake gets. The bug is not in your math — it is in the timing relationship between Unity’s render loop and the physics solver, and the fix is mechanical once you see what is happening.
The Symptom
A Rigidbody2D-driven object that should glide toward the mouse instead vibrates by 1–3 pixels every frame. The vibration is rhythmic, runs at the fixed timestep rate (50 Hz by default), and stops the moment you stop moving the mouse. Disabling the Rigidbody2D entirely and animating transform.position directly makes the shake disappear — but you lose collisions and your body tunnels through walls. You want both: smooth motion and physics.
What Is Actually Happening
Unity has two clocks. Update runs once per rendered frame and is unbounded — it runs as fast as your GPU allows. FixedUpdate runs at a fixed cadence (default 0.02 s, or 50 Hz) and is where the physics solver lives. Your code reads Input.mousePosition in Update and writes the new position to the Rigidbody2D in the same call.
Internally Unity batches that write into the next physics tick. Between the write and the tick, the renderer draws the body at the old physics position. On the next physics tick the body snaps to the new position. The next render frame draws the new position. If your refresh rate is higher than your fixed timestep (60 Hz refresh, 50 Hz physics is the worst case), some frames see the new position and some see the old, and you get a 1-frame-on, 1-frame-off jitter.
The Fix
Step 1: Sample input in Update, move the body in FixedUpdate.
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class FollowMouse : MonoBehaviour
{
[SerializeField] private float moveSpeed = 12f;
private Rigidbody2D _rb;
private Camera _cam;
private Vector2 _targetWorld;
void Awake()
{
_rb = GetComponent<Rigidbody2D>();
_cam = Camera.main;
}
void Update()
{
// Sample input every frame
Vector3 screen = Input.mousePosition;
screen.z = -_cam.transform.position.z;
_targetWorld = _cam.ScreenToWorldPoint(screen);
}
void FixedUpdate()
{
// Move toward the cached target on the physics clock
Vector2 next = Vector2.MoveTowards(
_rb.position, _targetWorld, moveSpeed * Time.fixedDeltaTime);
_rb.MovePosition(next);
}
}
The cached _targetWorld is sampled every render frame so the input is responsive, but the body only moves on physics ticks. The render loop never sees a half-applied physics step.
Step 2: Enable Interpolation on the Rigidbody2D.
Even with the FixedUpdate fix, the body still snaps from one physics position to the next. At 50 Hz physics, that snap is 20 ms long — visible if your render rate is 144 Hz. Set Interpolation on the Rigidbody2D to Interpolate. Unity will store the previous and current physics positions and lerp the rendered transform between them based on how far through the current physics tick you are. The visible motion becomes silky smooth.
Step 3: Never write transform.position on a Rigidbody2D.
This is the most common follow-up mistake. After fixing the timing, developers tweak the cursor offset by adding transform.position += offset in LateUpdate. This bypasses the physics solver entirely. The body teleports, ignores collisions, and reintroduces the jitter you just fixed. Always use MovePosition. If you need an offset, add it to the target before calling MovePosition.
When Interpolation Is Not Enough
Interpolation looks great when the body is moving smoothly, but it adds one physics tick of latency — the rendered position lags behind the simulated position by up to 20 ms. For action games where input feel matters, raise the physics rate instead. Open Edit → Project Settings → Time and lower Fixed Timestep from 0.02 (50 Hz) to 0.01666 (60 Hz) or 0.00833 (120 Hz). Higher physics rates cost CPU but eliminate the visible interpolation lag.
Do not raise the rate without measuring. A scene with hundreds of dynamic bodies can double its physics cost when you move from 50 Hz to 120 Hz. Use the Profiler to confirm you have headroom.
Verifying the Fix
Open the Game view, set the play resolution to a fixed window (not Free Aspect), and slowly drag the mouse in a horizontal line. With the bug, the body wobbles vertically by a pixel or two even though you only moved horizontally — that wobble is the physics tick fighting the render frame. With the fix, the line is dead straight. Bump your refresh rate up using Application.targetFrameRate = 144; in a debug script if you cannot reproduce on a 60 Hz monitor; the bug is more obvious at higher refresh rates.
“Whenever a Rigidbody is shaking, the bug is almost always in the relationship between Update and FixedUpdate, not in your math. Move the write into FixedUpdate and turn on Interpolation. That fixes 90% of the cases.”
Related Issues
For the same problem in 3D physics, see Unity physics jittery movement. If your Rigidbody is also falling through walls, check Unity Rigidbody falling through floor. For Cinemachine cameras shaking with the player, see Unity Cinemachine camera jitter.
If you cannot move the input read into FixedUpdate, at least cache it — never call Input.mousePosition inside FixedUpdate, that path skips frames.