Move Rigidbody locally, while inheriting rotation from 'parent' rigidbody

I’m wondering what the best way to do this is:

As an example here I have a blue block childed to a red block. As we’d all expect, rotating the parent transform rotates the child with it. The child can then be moved locally.

What I want is to to do this in code BUT with the rigidbodies instead. So I want the blue block to rotate WITH the red one when the red block gets rotated. But of course, rigidbodies don’t automatically inherit positions in that way.

What would be the best way to do it?

u1pbp

Here are my two scripts so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SetRbRotSlider : MonoBehaviour
{
    [Range(0f, 1f)] public float Value;

    public Vector3 AxisOfRotation;
    public float AngleOfRotation;

    private Quaternion _initialRot;

    Rigidbody _rb;

    // Start is called before the first frame update
    void Awake()
    {
        _rb = GetComponent<Rigidbody>();

        _initialRot = _rb.rotation;
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Vector3 offsetRot = AxisOfRotation * AngleOfRotation * Value;
        Quaternion offsetRotQuat = Quaternion.Euler(offsetRot);
        Quaternion targetRotQuat = _initialRot * offsetRotQuat;

        _rb.MoveRotation(targetRotQuat);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SetRbPosSlider : MonoBehaviour
{
    [Range(0f, 1f)] public float Value;

    public Vector3 AxisOfMovement;
    public float MoveRange;

    Rigidbody _rb;

    private Vector3 _offsetLastFrame;

    // Start is called before the first frame update
    void Awake()
    {
        _rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Vector3 offset = AxisOfMovement * MoveRange * Value;

        offset = transform.TransformDirection(offset);

        Vector3 offsetIncrement = offset - _offsetLastFrame;

        _rb.MovePosition(_rb.position + offsetIncrement);

        _offsetLastFrame = offset;
    }
}

Note: I’m trying to do all of this with rigidbodies because it will be interacting with other rigidbodies.

The “physically correct” way would be using joints. However, here’s a nice workaround that may allow you to keep using your scripts with rigidbodies:

Interesting, I’ll try this out. Thanks :slight_smile:

Did you end up finding a solid solution to this? I have a similar problem and I’m unable to get the rigidbodies behaving in a way similar to using the transform parent/child connection without rigidbodies!

The only way is using joints (or the kinematic workaround I referenced above). The Rigidbody component just overrides the Transform of the GameObject so it’s ruled by physics in World coordinates. The parent/child connection hasn’t any effect.