Search code examples
c#unity-game-enginevectorquaternionseuler-angles

Rotating Parent to Make Child Face Opposite Direction of Target's Forward


Scenario:

  • Parent P1 has Child C1
  • Target exists
  • All items' forward vectors face perfectly parallel to the X-Z Plane (pseudo 2D)
  • Positions of all objects are arbitrary
  • Child will never move on its own within Parent's space

Goal:

Rotate P1 exclusively about the Y-Axis to have C1 Face the opposite direction of target's forward vector

enter image description here

Note: Y-Axis Positive would face reader, Negative would go into screen

Implementation:

P1.rotation = Quaternion.LookRotation(-target.forward) * Quaternion.Euler(0, -C1.localEulerAngles.y, 0);

The above seems to work most of the time but breaks randomly and sometimes generates a Zero Vector as the forward. I am inexperienced with Euler Angles and Quaternions so my apologies in advance.


Solution

  • Using some quaternion algebra:

    Given this in Unity terms/c#:

    Desired child world = Quaternion.LookRotation(-target.forward)
    Child local = C1.localRotation`
    

    Given the equation for parent-child rotations:

    Desired parent world * Child local = Desired child world 
    

    We want to calculate desired parent world (P1.rotation). Take the above equation and multiply inverse(Child local) on right of both sides and simplify:

    DPW * child local * inv(child local) = Desired child world * inv(Child local) 
                    Desired parent world = Desired child world * inv(Child local)
    

    Expressing using Unity/C#, you get:

    P1.rotation = Quaternion.LookRotation(-target.forward) 
            * Quaternion.Inverse(C1.localRotation);