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.
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.
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.
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.
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.