1
\$\begingroup\$

The functionality I am trying to implement, consists of rotating one Transform and appling this rotation to other relevant Transforms in the scene. To make it a bit more clear: I have several objects in the scene. When I grab one (lets call it parent) and rotate it, the others (children) should rotate relative of their own position and rotation to the grabbed object around this grabbed object.

It is exactly the same what parenting does with its child objects when rotating the parent. Unfortunatly I cant just change the hierachy so I am bound to have different objects on the same hierachy level.

So far I have managed to rotate the children relative to the parent but when I grab the parent object the child objects first reorient themselves. After reorienting they do the right thing and rotate and move relative to the parent.

Here are two objects. The left one should rotate relative to the right one.

enter image description here

As the right one is grabbed and the procedure starts, the child object first jumps to another position with another rotation

enter image description here

I feel kind of stupid not seeing where this behaviour comes from. I use a coroutine to be able to construct the functionality in another script. As long as the coroutine is running, the child object should be moved and rotated relatively.

I first calculate the needed offsets of the position and rotation at startup:

    Vector3 offsetPos = child.position - parent.position;
    Quaternion offsetRot = child.rotation * Quaternion.Inverse(parent.rotation);

Then I apply the calculations in a loop:

    while (true)
    {
        child.position = parent.rotation * offsetPos + parent.position;
        child.rotation = parent.rotation * offsetRot;

        yield return new WaitForFixedUpdate();
    }

The loop runs as long as the parent object is grabbed and should place and orient the child accordingly.

I assume that my fault is located somewhere around calculating the offsets as once grabbed and reoriented, the children move and rotate exactly as they should.
If somebody has an idea where my mistake could hide I would be really happy if you could tell me.

Here is the related function as a whole:

    public override IEnumerator TransformGroupMember(Transform child, Transform parent)
    {
        //calculate offsets
        Vector3 offsetPos = child.position - parent.position;
        Quaternion offsetRot = child.rotation * Quaternion.Inverse(parent.rotation);

        //apply the relative transformation as long as the coroutine is running
        while (true)
        {
            child.position = parent.rotation * offsetPos + parent.position;
            child.rotation = parent.rotation * offsetRot;

            yield return new WaitForFixedUpdate();
        }
    }

Since this is my first question asked, I also welcome any suggestions about tips and tricks or changes.

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

You could use Transform.RotateAround function and just set the cube you need to rotate around as a target the other cube should follow target cube when you move it.

\$\endgroup\$
3
  • \$\begingroup\$ Hey, thank you for your answer! Unfortunatly I cant really make anything out of it as I need angles for the rotation. If I use Transform.RotateAround, I would first need to calculate the delta-angles of the axes from the grabbed cube between the FixedUpdate before and the current FixedUpdate. Then I would have to pass them to Transform.RotateAround, right? Did you mean it like this? \$\endgroup\$ Commented Aug 20, 2021 at 8:54
  • \$\begingroup\$ Yeah you would need to pass the needed angle to the function but when I read your question more clearly I get it that RotateAround() maybe is not really the best option so I am sorry for somewhat misleading answer. \$\endgroup\$
    – Ivan
    Commented Aug 20, 2021 at 13:13
  • 1
    \$\begingroup\$ Hey, I found out what the problem was. I posted an answer. Thank you that you invested your time into this and tried to help! \$\endgroup\$ Commented Aug 25, 2021 at 9:07
0
\$\begingroup\$

Okay, I guess I found a workaround.

Thinking about what I did I realised that the problem occures because I add the rotation of the "parent" to the "child" when I start the calculations in the while loop. So after calculating the offset position, which is a direction pointing towards the child, I have to rotate this direction inversed by the rotation of the parent. In the end the fist calculation step inside the while loop will rotate it back to its origin rotation, pointing towards the child again:

public override IEnumerator TransformGroupMember(Transform child, Transform parent)
{
    //calculate offsets
    Vector3 offsetPos = child.position - parent.position;
    Quaternion offsetRot = child.rotation * Quaternion.Inverse(parent.rotation);
    
    //workaround solution:
    offsetPos = Quaternion.Inverse(parent.rotation) * offsetPos;
    
    //apply the relative transformation as long as the coroutine is running
    while (true)
    {
        child.position = parent.rotation * offsetPos + parent.position;
        child.rotation = parent.rotation * offsetRot;

        yield return new WaitForFixedUpdate();
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .