Interpolation Still Occurs When Directly Setting Position/Rotation of a Kinematic Rigidbody

Hi,
I’ve noticed that when a rigidbody is set to kinematic and the Interpolation property is set to Interpolate, if I directly set transform.position or transform.rotation (as well rigidbody.position or rigidbody.rotation) the interpolation still occours, therefore the game object is not teleported. If the rigidbody is not kinematic, then it is correctly teleported.

I assume it is a bug because the manual here states “Teleporting a Rigidbody from one position to another uses Rigidbody.position instead of MovePosition.” Also, it can be useful from time to time to instantly move rigidbodies without interpolation, in particular if they are kinematic.

I’ve attached a simple project to reproduce the issue, in there I’ve increased the fixed time step to 0.2 to make the interpolation more noticeable. Pressing the mouse buttons sets the position or rotation of the cube.

8418540–1113561–Rigidbody Interpolation Issue.zip (74.5 KB)

I would assume it is working as intended, since Interpolation renders in-between positions of a body for frames where there is no physics update. It doesn’t and shouldn’t matter HOW the object is moved (re-positioned).

Furthermore, if you want instant teleportation, you can disable Interpolation by script, reposition the object, and turn it back on (possibly requires waiting for the next Update or FixedUpdate depending on how the interpolation handling is implemented by Unity).

I’m not sure it is intended to work that way, if rigidbody is not kinematic the position is immediately changed.

I presume this is 3D physics so I cannot really comment on the behaviour here but to be clear, when you set a position directly, it IS a teleport. Interpolation is an artifact of the Transform for visuals only, it’s not where the physics body is. Don’t confuse the two. Interpolation does NOT affect collision detection at all for 2D/3D physics.

Interpolation is a historic move where the Transform is behind where the body is i.e. it’s moving the Transform from the previous body position to the current one.

1 Like

Ah, I see! What you see is not where it is. So to speak. :smile:

Anyhow, I updated the test project to make it repeatable and switch between rigidbody and transform motion via flag on the script. The project serves as a good test case what happens when you set the transform.position/rotation of a physics-enabled object, rather than using the rigidbody.position/rotation. I can only describe it in words:

  • User clicks and cube transform is set to move 2 units up
  • First frame: Cube is rendered at position 2 units up
  • Next frame(s): Cube is rendered back down near position 0 as it starts interpolating - it does so until it reaches position 2 units up.

So you get a very noticable, distracting, ugly fraction of a second flickering of the object being rendered at its target destination, then interpolation kicks in. This does not happen when using rigidbody.position.

I’ve seen this in Unity projects before and could never explain what kind of evil things the dev might have done for this sort of thing to occur.

8418684–1113606–Rigidbody Interpolation Issue.zip (32.5 KB)

1 Like

That’s right, I actually meant visual teleport. Still there is an inconsistent behaviour between kinematic and non rigidbodies.

It may be that is not a bug and it’s intended to work like that, maybe, since kinematic rigidbodies are usually moved by directly setting the transform, they’ve choosed a different implementation. However to me in this way they introduced a limitation for kinematic rigidbodies.

Disabling interpolation right before setting the position and re-enabling it right after as you suggested seems to do the trick.

Kinematic bodies are meant to be changed via the Rigidbody API just like any Rigidbody. The only reason the Transform is supported to do anything is because devs do it.

But yeah, if there’s an inconsistency for interpolation between the two methods, I’m not sure why. You could raise a bug report querying it.

2 Likes

It seems this issue was already fixed (?) :slight_smile:
2020.3 on the left, 2022.1 on the right. Time step = 0.1s:

https://www.youtube.com/watch?v=T1POuWw1qTI

Vector2 velocity = 2 * Vector2.right;
void FixedUpdate()
{
     rigidbody.position += velocity * Time.deltaTime;
}

I remember that 2D interpolation was not affected by changing the body position directly (FixedUpdate). However, changing the transform should stop it (Unity 2020.3 or higher).

Personally, i think these “small” but sometimes annoying differences between 2D and 3D (outside of the physics engine) should be eliminated if possible. It is great to see that Unity is moving towards that goal, or at least it seems so.

1 Like

Indeed! I just checked with 2022.1.15f1 and there is no zapping around when setting the transform with interpolation enabled.

Well, that’s nice.