So the 2D Platformer Microgame example that comes in the Learning section of the hub seems to violate the idea that you should never move the position of the rigidbody2d (or 3d) manually. This causes a forced physics recalculation. However if you look at the code they use:
Worth noting that the rigidbody is set to kinematic. So I guess my question is, am I missing something and there is an exception to that rule? Or did this example ship with a bad technique?
My hope is there is a gotcha here and that with kinematics you can just move them. Would make my life A LOT easier. But if is forces a recalc, that is not great. Anyone with insight on this, thanks ahead of time. Sorry if this has been discussed before somewhere.
Thanks for the reply and the binding source links. I would hope this to be the case, but I think that MovePosition sets the velocity so that the body arrives at the position on the next fixupdate. It is part of the reason I am not using it. It seems to just hijack the velocity for the next cycle. I think that setting the rigidbody’s transform position literally teleports the body to that position, which is why the physics engine needs to do a recalc. But I could be way off base here.
Would be interested to hear what is going on under the hood with this. Not sure if it being kinematic throws that all out the window too.
Either way, appreciate the input.
MovePosition will move an object while rigidbody2D.position will teleport an object. And it’ll do it in a more efficient way compared to setting transform.position directly.
BTW - The issue with the above line of code is that the movement wouldn’t be interpolated. I’ve not seen the demo and so I’ve no idea why they chose that method for moving the object.
Setting this directly will teleport the body instantly to that position which might be required depending on what is happening. After that call, the body will be there along with any attached colliders. You could test this by immediately doing any physics query such as raycast, shape-cast etc. In other words, the body and all its colliders are immediately update in the physics broadphase tree.
If you don’t use queries to check if you can/should position the body there then you have the potential to cause overlap. Being Kinematic it won’t move out of overlap because it has no collision rersponse but anything Dynamic will of course be moved out of overlap.
Alternately, MovePosition/MoveRotation will move via linearVelocity/angularVelocity when the next simulation runs i.e. it’ll move just like a Dynamic body would. If this is on a Kinematic body though then it still won’t stop or react upon contact but it will move other dynamic stuff out of the way. So in theory they’re not that much different. An important difference is that setting either the Transform (no!) or the Rigidbody2D position/rotation directly doesn’t work with interpolation; the reason is that you don’t want it interpolating over a large distance if you were doing a large reposition. MovePosition/MoveRotation does work with it because it’s just using its velocity for movement.
Personally I would always use MovePosition/MoveRotation if it’s typical small-delta movements. If you suddenly want the body to appear somewhere else then you should directly set its position directly.
As a side-note, if you were to change the Transform, only the Transform changes as it doesn’t notify anything else (nothing in Unity) that it has changed so physics would only know when it runs the simulation where it’s forced to reposition the body and depending on where you set it, it might have to completely recreate a collider that isn’t attached to a Rigidbody2D;this is to be avoided as it’s expensive.
Just to sum it up, I am trying to roll a custom platformer system. I like how Godot does their CharacterBody2D and it just uses kinematics and you can then just handle the movement yourself. So I am trying to do something similar, and the learning demo seemed to do something like that so I was picking it apart to learn from it. I could definitely figure out how to deal with the math to make MovePosition work, especially since interpolation wasn’t something I had accounted for. But there is another issue/question that arises with this I will ask here shortly.
First off, just to make sure I am understanding this correctly, the big NO for manually movement with the physics system is moving the GameObject’s transform and not the RigidBody2D’s position? So moving the RigidBody will not incur the physics extra overhead?
The second question, is I would like to achieve something similar to Godot’s CharacterBody2D “snap” feature. It allows the body to snap to the surface so that it does not shoot off of it. Example is running up a hill that flattens at the top. The body will stay on the surface ignoring the forces the would launch it up. Not sure if you have any ideas on that. This particular feature was where I ran into issues with MovePosition “locking” the character in place in order to snap them to the surface. I get that this is a skill issue on my part lol, but curious if you had any tips or ideas?
Thanks again MelvMay and others for the help on this.
MelvMay, you are a savior. Thanks, this is exactly what I needed. I’ll mark the other answer as the solution, but this is also extremely useful. Thanks again!