Search Unity

Resolved How to rotate transform towards its child transform rotation?

Discussion in 'Scripting' started by DirtyAlien, May 18, 2022.

  1. DirtyAlien

    DirtyAlien

    Joined:
    Jan 20, 2017
    Posts:
    4
    I have hierarchy of objects like this:

    ...
    |- Holder (just a Transform)
    |- MyObject (has MeshRenderer attached)
    |- Orientation (just a Transform)

    "Orientation" represents desired visual orientation of it's parent "MyObject".
    All three objects has their own non-identity localRotations, but all localPositions are Vector3.zero.

    What I want to do is to apply some rotation to MyObject.transform.localRotation so Orientation.transform.forward will match Holder.transform.forward

    So I wrote the code:

    // Get the rotation difference between Orientation and Holder in world space
    var rotationDelta = Quaternion.FromToRotation(Orientation.transform.forward, Holder.transform.forward)
    // Apply it to MyObject local rotation
    MyObject.transform.localRotation *= rotationDelta;

    But it does not work and give weird results :(
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Well once you rotate the parent to match the child that will in turn rotate the child (since children rotate along with their parents). So doing things this way is not really going to work well. You'll want to restructure things so that the Orientation object is not a child of MyObject. Once that's the case you can just do:
    Code (CSharp):
    1. MyObject.transform.rotation = Orientation.transform.rotation;
    Or simply use a Rotation Constraint rather than writing the code yourself:
    https://docs.unity3d.com/Manual/class-RotationConstraint.html
     
  3. DirtyAlien

    DirtyAlien

    Joined:
    Jan 20, 2017
    Posts:
    4
    Thanks for your reply!
    Unfortunately, your code snippet won't work because MyObject.transform.rotation already has some rotation and I need to compensate it (not override).

    Let me provide some images.

    I added arrows which specifies forward directions of all 3 transforms. This is how my test scene looks:

    This is what I want to achieve: forward vector of Orientation (pink arrow) lying on forward vector of Holder (blue arrow)


    And this is what happens if I run your code:


    My script for MyObject based on your code snippet:
    Code (CSharp):
    1. public class TestRotation : MonoBehaviour {
    2.         public Transform Holder;
    3.         public Transform Orientation;
    4.  
    5.         private void Start()
    6.         {
    7.             transform.rotation = Orientation.rotation;
    8.         }
    9.     }
    :(
     
  4. DirtyAlien

    DirtyAlien

    Joined:
    Jan 20, 2017
    Posts:
    4
    Oh, now when I have test scene with visual representation of forward directions I understood how to make it:
    Code (CSharp):
    1. transform.rotation = Holder.rotation;
    2. transform.rotation *= Quaternion.Inverse(Orientation.localRotation);
    It's basically: rotate MyObject towards Holder and then compensate by localRotation of Orientation
    It took me 4 hours to realize how to write this trivial 2 lines of code :) I wish Unity will make more study materials on Quaternions because it's always been a headache for me (currently you can't find any good videos on youtube with cases explaining usage in actual applications)