Physics2D.UpdateTransforms takes longer when Rigidbody2D is set to Static instead of Kinematic

In a blank project, I’ve copy-pasted around 100 objects with a SpriteRenderer, BoxCollider2D, AudioSource, and Rigidbody2D. These objects also have a couple of children with their own BoxCollider2Ds (the object was copied from my main project).

When the rigidbody is set to static, Physics2D.UpdateTransforms takes around 0.05ms to complete. If I switch them all to kinematic, it only 0.005ms. Auto Sync Transforms is turned off in the Project Settings.

Is this intended behavior? My understanding was that UpdateTransforms only gets called if you move a transform directly instead of moving the rigidbody. But, in a blank project with no script attached, I don’t think I’m accidentally moving the transforms at all - and furthermore, I wasn’t expecting static to produce much slower results than kinematic. (0.05ms is pretty fast of course, but it’s much slower on the Switch than on a desktop computer).

“Physics2D.UpdateTransforms” is the physics engine writing the body poses back to the Transform system after the simulation step. It’s not it reading the Transforms and writing them to the body poses which you seem to be referring to when you’re referring to modifying the Transforms.

Honestly, I’d need to see a simple reproduction case to be able to comment.

Hmm, okay. How can I upload a repro case? Should I put a zip somewhere, or send it in as an actual bug report?

It’s not a bug. Can you not zip it and attach it here? A small repo should be tiny as long as you delete all the redundant folders like “Library”, “obj” & “logs” and any IDE files.

Either that or DM me with your email and I can set-up a workspace for you to upload it to.

All right, I copied the setup into a new project. In the Physics Test scene, you should see that UpdateTransforms takes longer when the clouds’ rigidbodies are set to Static rather than Kinematic.

9455570–1327820–Repro.zip (80.7 KB)

Could you please write instructions on how to reproduce.

I get the rough idea of what you change exactly (presumably select all the prefabs and change the body-type) but that’s an assumption.

Knowing you hit Play, do X, select Y, look at Z then stop and do something else is important so I can see what you’re seeing.

Forgot to say, I’ll take a look at this today for you!

Thanks! Sure, it’s basically just:

  • Make sure the body type of the prefabs is set to static
  • Hit play
  • Look for Physics2D.UpdateTransforms in the profiler
  • Take note of how long the operation takes (on my computer it’s around 0.05 ms)
  • Stop
  • Change all the body types to kinematic
  • Hit play and check profiler again
  • For me, Physics2D.UpdateTransforms now takes something like 0.01 ms
1 Like

Thanks. Yes, well that’s absolutely not what you’re supposed to get. If anything, Static should be the fastest so there should be something we can do here to improve it.

I’ll take a look in the next hour or so but I’ll get back to you when I’ve figured out what’s going on.

Thanks for reporting it.

I can confirm that I’ve reproduced the above so I’ll dig deeper into what’s going on here and report back to you.

Thanks again for the report.

NOTE: In later versions of Unity, this has been renamed to “Physics2D.WriteTransforms”. It means the same thing though.

1 Like

So what is happening here is that the Kinematic bodies appear faster because they are sleeping. If you do anything to them or set their Sleeping Mode to “Never Sleep” then they’ll take approximately the same amount of time, maybe slightly more.

Also, if you remove the Static Rigidbody2D then, in this case, there’s no overhead at all. You obviously can do this if you never intend to move the collider. This just adds those colliders to the hidden Static ground-body that lives at the world origin. If you intend to move these then you should be using a Kinematic body really but in some cases, a Static body is preferably as it avoids everything in the simulation step itself.

The cause of problem here (which is going to be tricky to solve) is that whilst Static bodies are permanently asleep, they always quickly assert their position to the Transform. Now this is an odd statement because Static bodies are never meant to move right? Whilst this is true, as a bug fix many, many years ago, users were setting parent transforms causing the Transform the child Static body is on to become out-of-sync with the pose of the body itself. To solve this, the Static body always writes its pose after the simulation step. We always do this because it’s permanently asleep. That’s fast but it’s still a non-zero cost.

Looking again at it, we should avoid this if possible but it’s not a simple thing to improve as a change to a parent Transform isn’t something easily detected without performing more work which goes against what we’re trying to do which is do less work.

I’ll continue to look at this later and let you know what can be done here but thought I’d update you and allow you to verify what I said above on your side too.

1 Like

Interesting! Thanks for the update. Good to know how it works, at least.

For this one, the objects don’t move, but I think I was using a Rigidbody because I wanted to receive the OnTriggerEnter events from the child colliders. Otherwise I would just use a collider without a rigidbody.

It’s not a huge bottleneck for me either way, but do let me know how the progress goes. In this particular case, it might actually be better for me to set the objects to kinematic and allow them to sleep — kind of a funny workaround, but it makes sense given your explanation.

1 Like