This question comes after having a discussion with some students about 2D Physics in Unity. I was making several points about how to move objects:
Never ever move a collider which doesn’t have a Rigidbody2D attached.
If you need to move something in a script, such as a player or a platform then, it should have a Rigidbody2D set to kinematic and you then use the Rigidbody2D.MovePosition method or set Rigidbody2D.velocity, but never ever set the transform directly.
Some students have bought assets to help with their personal 2D game development, one which seems popular is the “Corgi Engine”. In that asset it was pointed out that all the movement is using the transform directly (usually transform-translate) on game objects which have a Rigidbody2D (kinematic), and some which only have a collider.
@MelvMay is the advice in the Unity docs and your various post on the subject still valid for 2D physics (1 & 2 above) or have updates changed things and those points don’t apply?
Yes, the only thing that moves is a Rigidbody2D. There’s no reason why this would’ve changed though as we still use Box2D for 2D physics.
A collider is created against a body (encapsulated by a Rigidbody2D). Its geometry is local to the body which is why, when a body moves, the collider geometry does not need to be modified, only its position in the broadphase (spatial database).
When you don’t specify a Rigidbody2D we create it against the Static (non-moving) ground body that lives at the world-origin with no rotation. We do this because it’s how physics shapes (shapes that compose colliders) are created. For such a collider, its local-space geometry is identical to its world-space because the body it’s attached to is at the world-origin.
Colliders (and their physics shapes) cannot move relative to the body they are created against. This is why, when you modify a Transform which changes how the collider is positioned relative to the body it’s created against, it has to be recreated with new geometry.
You’ll see this collider recreation appearing and the cost associated with it in the profiler. You’d also see that if you added a Rigidbody2D to the same GameObject, the cost goes away.
If a collider needs to move then use a Rigidbody2D and select one of its three body-types.
Terrible practice. Changing the Transform doesn’t change anything else until the system that component uses runs. For renderers, this is per-frame so when they render, they read the Transform. Likewise, for physics components, when the physics system runs (by default during the fixed-update), it’ll see the user has changed the Transform and instantly relocate the Rigidbody2D to that position and/or recreate any Collider2D geometry at that location.
So it’s an instant “teleport”. The Rigidbody2D isn’t moving. This is why continuous collision detection and interpolation don’t work when you do this, the Rigidbody2D is not moving. It just steps from position to position.
If you’re changing the Transform, you’re doing it wrong.
The only exception to this is scale because the physics system doesn’t support scaling natively. It wants everything pretty much immutable with bodies moving around.