This site uses strictly necessary cookies. More Information

X# Why is this multiplication of two quaternion rotations not working correctly

Hey guys, I have the following problem: I want to rotate a coordinate system relative to a sphere with the following constraints:

a) y-Axis points away from the center of the sphere (priority1)

b) z-Axis matches with the spheres z-Axis as well as possible (priority2)

Unitys LookRotation() basically does this job, but in the opposite way. While I need to perfectly align the coordinate Systems y-Axis and secondary the z-Axis, this method perfectly aligns the coordinate Systems z-Axis and secondary the y-Axis.

To finally meet my conditions I had the idea to first use LookRotation and afterwards rotate the coordinate System around its x-Axis to align the Vectors correctly, but this doesn´t work as expected. Can you please help me with this problem? Am I doing anything wrong or do I misunderstand the multipication of quaternions?

Thats the code i wanted to use:

```
CoordinateSystem.transform.rotation = Quaternion.LookRotation(CoordinateSystem.transform.position, Vector3.back) * Quaternion.AngleAxis(90, CoordinateSystem.transform.right);
```

**Answer** by SilverLife
·
May 09, 2019 at 08:26 AM

First of all I am really thankful for your help, I really appreciate it! THANK YOU! Secondly, I think I might haven´t explained the Problem detailled enough and I am really sorry about this!!! Finally I figured out a way to make it work. Now I will share my solution with you, but first of all I will again explain my problem in detail. Currently I am developing a Flight Simulator. Therefore I receive my position-data as lat-long geo-coordinates. To create a local coordinate System for my plane where I can apply pitch, bank and yaw angles the basic plane coordinate System has to be always parallel to a spheres surface which in my case is the Earth .

Secondly this plane coordinate System has to aways point towards the Earth´s North-Pole with it´s z-Axis, but it still has to be parallel to the Surface. (see the Picture, the red dot is the North pole, the xyz-axis is the one of my plane-coordinateSystem as it should be)

I guess there are 3 ways to reach this goal:

The first is a complex combination of rotations, manually calculated (what I tried in the beginning but my calculation(which obviously was not correct) didn´t work at each earth hemisphere so I was looking for another solution)

The second, which we discussed here is, to combine the lookRotation() with another one to just swap the z and the y axis make it point in the correct direction.

**Finally my solution was, to add a parent gameObject. I applied the lookRotation() to this parent Object. The parent's child is my basic plane coordinateSystem and as default I gave it the Rotation x = Now the parent has x pointing away from the earth Center and y pointing towards the South Pole. With the Default x-rotation of the child object I swapped those two vectors and got what i was Looking for.**

If you can help me with the second solution way (the one where lookRotation is used with a second Rotation) to learn how this would have worked it would be great, just to enhance my knowledge, because I don´t like the current solution with the extra GameObject.

I get nice results with the code I gave you in my comment, I've reworked it a little bit

```
public Transform Earth;
public Transform NorthPole;
public Transform CoordinateSystem;
void LateUpdate()
{
Vector3 up = (CoordinateSystem.transform.position - Earth.position).normalized;
Vector3 forward = (NorthPole.position - transform.position).normalized ; // Or Earth.forward if you know the north pole is located at the surface of the +Z axis of the earth;
Vector3 right = Vector3.Cross( up, forward );
forward = Vector3.Cross( right, up );
CoordinateSystem.transform.rotation = Quaternion.LookRotation( forward, up );
}
```

Your reworked code gives me perfect results too, I don´t know why it didn´t behave correct the first time, it might be my fault ;)

Thank you very much man!

**Answer** by Hellium
·
May 07, 2019 at 09:39 AM

The quaternion product is not commutative, and the correct order is this one:

```
CoordinateSystem.transform.rotation = Quaternion.AngleAxis(90, CoordinateSystem.transform.right) * Quaternion.LookRotation(CoordinateSystem.transform.position, Vector3.back) ;
```

Hey Hellium, thank you for your answer! Unfortunately this doesn´t work either. It still results an unexpected roatation! Is there maybe another way to reach my goal?

I got correct results when I tried in an empty project.

$$anonymous$$y first suggestion was the following, but I think you will get the same results:

```
void LateUpdate()
{
Vector3 up = CoordinateSystem.transform.position - SphereTransform.position;
Vector3 forward = SphereTransform.forward;
Vector3 right = Vector3.Cross( up, forward );
forward = Vector3.Cross( right, up );
CoordinateSystem.transform.rotation = Quaternion.LookRotation( forward, up );
}
```

If you don't have a `SphereTransform`

:

```
void LateUpdate()
{
Vector3 up = CoordinateSystem.transform.position;
Vector3 forward = Vector3.forward;
Vector3 right = Vector3.Cross( up, forward );
forward = Vector3.Cross( right, up );
CoordinateSystem.transform.rotation = Quaternion.LookRotation( forward, up );
}
```

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Rotate non-forward vector to face direction? 0 Answers

Applying multiple rotations 1 Answer