How to teleport a kinematic Rigidbody2D with the interpolation settings on?

I would like to start by quoting some parts of the documentation. The first thing that catches my eye is the difference in the description of the MovePosition methods of Rigidbody and Rigidbody2D components.


Moves the kinematic Rigidbody towards position.

Rigidbody.MovePosition moves a Rigidbody and complies with the interpolation settings. When Rigidbody interpolation is enabled, Rigidbody.MovePosition creates a smooth transition between frames. Unity moves a Rigidbody in each FixedUpdate call. The position occurs in world space. Teleporting a Rigidbody from one position to another uses Rigidbody.position instead of MovePosition.


Moves the rigidbody to position.

Moves the rigidbody to the specified position by calculating the appropriate linear velocity required to move the rigidbody to that position during the next physics update. During the move, neither gravity or linear drag will affect the body. This causes the object to rapidly move from the existing position, through the world, to the specified position.

Because this feature allows a rigidbody to be moved rapidly to the specified position through the world, any colliders attached to the rigidbody will react as expected i.e. they will produce collisions and/or triggers. This also means that if the colliders produce a collision then it will affect the rigidbody movement and potentially stop it from reaching the specified position during the next physics update. If the rigidbody is kinematic then any collisions won’t affect the rigidbody itself and will only affect any other dynamic colliders.

2D rigidbodies have a fixed limit on how fast they can move therefore attempting to move large distances over short time-scales can result in the rigidbody not reaching the specified position during the next physics update. It is recommended that you use this for relatively small distance movements only.

It is important to understand that the actual position change will only occur during the next physics update therefore calling this method repeatedly without waiting for the next physics update will result in the last call being used. For this reason, it is recommended that it is called during the FixedUpdate callback.

Note: MovePosition is intended for use with kinematic rigidbodies.

The description of Rigidbody2D.MovePosition seems to be more detailed but then the question arises whether the differences in the descriptions mutually applicable (to both types of rigidbodies)?

For example, the Rigidbody.MovePosition description sounds like it moves only a kinematic rigidbody. It also explicitly states that MovePosition complies with the interpolation settings and position should be used for teleportation needs.

The last sentence looks like an exact answer to my question if all this were true. But at least this is not the case for Rigidbody2D: my experiments have shown that both: Rigidbody2D.MovePosition and Rigidbody2D.position complies with interpolation settings.

The first part of this video demonstrates the movement of 2 Rigidbody2D kinematic objects with interpolation via MovePosition & position. Then I turn off interpolation and play the same scene. Time is set to 0.01, so you can easily observe that interpolation works in the first part and does not in the second. Also in the first part you can notice that changing Rigidbody2D.position with interpolation settings on really teleports the object (as documentation claims) but only in the first FixedUpdate, then it is interpolated along with Rigidbody2D.MovePosition.

So, my questions are (still the main one is the 3rd):

  1. Is the differences in the descriptions mutually applicable (to both types of rigidbodies)?
  2. Why does Rigidbody2D.position interpolate the object after the first FixedUpdate while it shouldn’t?
  3. What is the correct way to teleport the kinematic Rigidbody2D with the interpolation settings on?

The only way I could come up with is turning interpolation off & on:

Rigidbody2D rb = player.GetComponent<Rigidbody2D>(); RigidbodyInterpolation2D interpolation = rb.interpolation; rb.interpolation = RigidbodyInterpolation2D.Interpolate; rb.position += (Vector2)shift; rb.interpolation = interpolation;