Rigidbody 2D doesn't move when parented to a moving object?

Hello, I have a Kinematic RigidBody2D that I’m moving through code.

Everything works perfectly until I parent it to a moving platform, when that happens the rigidbody just completely stops working and won’t move at all.

Note: If the platform stops moving, the rigidbody suddenly works and can move again, however when the platform moves, it stops.

any ideas?

i’m not exactly sure what kind of game you are doing but for the platformer i was working on my Player wasn’t being able to stick to the Moving platform and it was not moving with it so i added this code to my Moving Platform and it worked Perfectly :-

    //When the player lands on the Platform
    void OnCollisionEnter2D(Collision2D col)
    {
        col.gameObject.transform.SetParent(gameObject.transform, true);
    }


    //when the player takes off the Platform
    void OnCollisionExit2D(Collision2D col)
    {
        col.gameObject.transform.parent = null;
    }

What the code does is Parenting the Player to the Platform and you’ll be able to move on it without falling and once you leave it you wont be a child to the Platform anymore. but my rb is Dynamic for sure.

The Rigidbody2D doesn’t know anything about hierarchies. When you add it to a GameObject, you’re asking it to drive the Transform (from its internal pos/rot pose). You should NEVER modify the Transform yourself from then on. If you stick it as a child and start modifying the parent Transform, all it sees is that you’re constantly overriding the Transform which is the whole point of it being there so it has to read your changes back into its pose (because you updated it right!). It then tries to move and writes its updated move to the Transform and then again, you stomp over it. It’s not “moving” because you’re setting the position of the whole hierarchy.

In short, you’re creating a conflict. You might want some “logical” behaviour but that’s not what it’s there for.

The Rigidbody2D doesn’t write some “relative” motion i.e. it writes the world-space to the Transform, not the local-space of that Transform.

1 Like

Thanks for the replies!

Sorry if my post was a bit vague, the player attaches + moves with the platform just fine, but the player itself becomes frozen to the platform, as his own movement stops functioning when it moves, as @MelvMay described.

private void AttachPlatform(Transform transform){
    Unit.transform.parent = transform;
}

public void FixedUpdate(){

    //Body: Rigidbody2D -- This stops working when the parent transform moves
    Body.position += new Vector2(Velocity.x, Velocity.y) * Time.fixedDeltaTime;

//...[other code]
}

Ahh very informative, that’s exactly what’s happening!

However, I can’t find a solution here. Localposition workarounds don’t seem to do anything as you said I shouldn’t modify it’s transform, nor does script execution order.

Is there a proper way to do this?

Dont use anything with transform if you are using a rigidbody, 2D or otherwise. You need to use AddForce or MovePosition functions or even set the velocity directly. In your script above you are trying to move the position part of the transform directly.

Something like this is what you should do:

void FixedUpdate()
    {
        rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
    }

I tried that as well with the exact same outcome, I believe that does the same process as moving the position?

Then try using AddForce or setting the Velocity itself. Continue to debug by adding debug.logs through the code to see what is and what is not working. If that doesnt work you probably need to change how you attach to moving platforms.

Oh that’s right I forgot, MovePosition breaks the moment the rigidbody touches another collider for any reason.

The RigidBody2D is Kinematic however as it has very precise movement, so Forces/Velocities won’t work.

Edit: Just removed the RigidBody2D completely and I’m now using purely transform.position and everything works perfectly. Might attempt it again some time in the future.

No, MovePosition is just a helper that calculates the velocity needed to move the body during the next simulation step therefore works on Rigidbody2D that can move which are Dynamic and Kinematic body-types. It doesn’t exist as a feature in the 2D physics system. If you use a Dynamic body-type then of course those body-types encounter collisions so cannot be guaranteed to get to the position! It doesn’t “break” MovePosition.

It’s not more precise. It just doesn’t react to collisions and ignores any forces. It does however allow you to set linear/angular velocity perfectly fine. This is the whole point of the Kinematic body; a body where you are explicitly and completely in control. The physics system won’t move it.

Saying you’re going to remove it and directly drive the Transform makes zero sense unless you’re also not going to use Colliders either so no 2D physics. You can have a Rigidbody2D set to be Kinematic and set its position which is IDENTICAL except that it doesn’t cause its attached colliders to be recreated every time it moves!!

If you’re using collider then use a Kinematic body. If you don’t do this then your Colliders will be recreated each time you modify the Transform as they are automatically attached to the Static Ground Body which lives at the world origin. Modifying the Transform therefore changes all their geometry. Collider geometry is always relative to the body they are attached to.

In short, if a collider “moves” in 2D physics, make sure you move the Rigidbody2D it’s attached to.

If you don’t want it to ever write to the Transform then add a Rigidbody2D and set its body type to Static. This is identical to NOT having one except again, it’ll mean the colliders won’t be recreated.

1 Like