Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Child rigidbody doesn't act normally when parent rigidbody moves

Discussion in 'Physics' started by Stranger-Games, Oct 5, 2018.

  1. Stranger-Games


    May 10, 2014

    I have a physical object that moves using rigidbody. It has a child with its own collider and the collider act as expected, for example if there's an object above a child collider and the parent rigidbody moves, the object lying above the collider is affected correctly.

    image of parent object (the small box above is affected with parent rigidbody movement if the child doesn't have rigid body)

    image of the child object with rigidbody added (the small cube above isn't affected with parent rigidbody movement after adding rigidbody to the child)

    However if I add to that child collider (like in second image) its own rigidbody and moved the parent rigidbody, the child collider acts as if non physical transform is called. For example if there's an object above the child collider with the rigidbody, it's not affected with the movement at all.

    The reason I want to add a rigidbody to that child object is because sometimes I want to move the child independent from its parent rigidbody. Which works correctly, but I want it also to work correctly when the parent rigidbody moves even if the child has its own rigidbody.

    Scenario 1: child has no rigidbody, moves with parent and affects other bodies (small box above)
    child working 2.gif

    Scenario 2: child has rigidbody, moves with parent but doesn't affect other bodies (small box above)
    child not working.gif

    Scenario 3: child has rigidbody but moves independent from parent rigidbody, affects other bodies correctly (small box above)
    child independence.gif

    Thanks for advance
  2. Edy


    Jun 3, 2010
    The Rigidbody component just overrides its GameObject's Transform so the world position and rotation come from the physics engine. The hierarchy doesn't have any effect as the final world pose is overriden. If you need some Rigidbody to move using another Rigidbody as reference, then you must do it explicitly. Some possible methods I can figure out:
    • Configure the child rigidbody as Kinematic, then use Rigidbody.MovePosition and Rigidbody.MoveRotation (from FixedUpdate) to ensure its position is related to the reference.
    • Attach both rigidbodies via Configurable Joint
    • Apply forces / torques (or even velocities) via Rigidbody.AddForce / Rigidbody.AddTorque to the child rigidbody based on the difference with the ideal position it should have based on the reference. Note that this is pretty much what a joint does, but doing it this way allows to configure behaviors not directly supported by the joint.
    Stranger-Games likes this.
  3. Stranger-Games


    May 10, 2014
    Thank you very much for your reply and details.

    I tried Fixed Joint approach and configuring the child rigidbody as kinematic and using Rigidbody.MovePositions. Both approaches had problems.

    First the fixed joint approach. The fixed joint works as parent/child as I wanted. But I wanted sometimes to move the child a little in its local space keeping the fixed joint effect. I did the following to change connectedAnchor but unfortunately the parent seems to move also for some reason. I don't want the parent to move in this code I only need the child to move in its local space while keeping the joint. (The parent is below i the gif)

    Code (CSharp):
    1. void Start () {
    2.         joint = GetComponent<FixedJoint>();
    3.         joint.autoConfigureConnectedAnchor = false;
    4. }
    6. void FixedUpdate() {
    7.         var newAnchor = joint.connectedAnchor + Vector3.right * multiplier;
    8.         joint.connectedAnchor = newAnchor;
    9. }
    Fixed Joint connected anchor.gif

    I tried the same code with configurable joint but I get the same effect of the parent moving also opposite to child movement.

    The approach of Rigidbody.MovePosition has two main problems. First I don't want my child to be kinematic. I want if something hit my child that should also move the parent from the shock keeping the parent/child as it is. Fixed joint did this effect perfectly but had the problem above.
    The second problem with Rigidbody.MovePosition is that I don't have the child/parent movement in sync when the parent is accelerating/decelerating. As you can see when the parent at the bottom have force in one direction or opposite direction there's a slight delay in the child following it. The code I use is below the image.


    Code (CSharp):
    1. void Start () {
    2.         rigid = GetComponent<Rigidbody>();
    3.         relativePos = transform.localPosition;
    4.         relativeRot = transform.localRotation;
    5.     }
    7. private void FixedUpdate() {
    8.         Vector3 newPos = new Vector3();
    10.         newPos = transform.parent.TransformPoint(relativePos);
    12.         rigid.MovePosition(newPos);
    13.     }
    The same delay happens using the code below also

    Code (CSharp):
    1. private void FixedUpdate() {
    2.         Vector3 newPos = new Vector3();
    3.         var parentPos = transform.parent.GetComponent<Rigidbody>().position;
    4.         newPos = parentPos + relativePos;
    6.         rigid.MovePosition(newPos);
    7.     }
    Thanks for advance.