1
\$\begingroup\$

So I am trying to orient a gameObject ( house in the picture below) which is nothing but a plane and has a 2d texture on it as you see below. The whole game is made on a hex sphere. I am using Orthographic camera projection for this game. I have oriented the house plane to the normal of the tile and rotated it by 90 degrees in x axis to begin with

cityDummy.transform.rotation = Quaternion.LookRotation(normal);
cityDummy.transform.Rotate(90, 0, 0);

Now I am trying to orient the house to make it look at the center ( blue capsule object in the image is the center point ) but I don't want to rotate it in all angles. Basically that is what LookRotation or LookAt does inside Unity. So after orienting the house with the normal, how do I make the house object look at the center and just rotate it in one axis that would be the y-axis in this case?

enter image description here

The reason why I need to do this is first of all I want to orient the house texture to the normal of the tile it gets placed on as you see in the image above. That works fine.

Now the next thing is we want them to face the south which is the blue capsule in the image above. So they would still be oriented like in the image below but the forward of the city should be facing south or towards the blue capsule. If I do LookAt it messes up the current orientation as it rotates in all axis. I would only want to rotate it on one axis and make it face the capsule

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you try and explain or display what effect you desire as the result. \$\endgroup\$ – Shroeder Nov 12 '14 at 16:27
  • \$\begingroup\$ I have updated my post towards the end. \$\endgroup\$ – ckzilla Nov 12 '14 at 17:14
  • 1
    \$\begingroup\$ If you take the 3d plane for your cell and the line for that south pole, and find the intersection point, then you could use LookAt for that point. You would also want to handle the case where the plane is parallel to that line. \$\endgroup\$ – radical Nov 12 '14 at 17:52
1
\$\begingroup\$

Quaternion.LookRotation(forward, up) has a nifty property:

  • it rotates z+ exactly to forward
  • it rotates y+ as close as possible to up (given the constraint on z+)

(You might not be used to up, since it silently defaults to (0, 1, 0) if you leave this parameter out)

What we want here (and this comes up pretty often) is the reverse: we want y+ controlled exactly, and we want z+ to get as close as possible given this constraint.

We can get this just by playing with the axes a bit:

Vector3 lookDirection = target.transform.position - cityDummy.transform.position;

Quaternion rotation = Quaternion.LookRotation(normal, -lookDirection)
                    * Quaternion.AngleAxis(90f, Vector3.right);

This looks weird, so let me unpack it a bit...

We're using Quaternion.LookRotation with normal in the first position (ordinarily used for forward), to ensure the resulting rotation sticks to normal exactly, and then aligns as close as possible to (negative) lookDirection.

This gives us a rotation where the local z+ is pointing in the normal direction, and local y- is pointing toward lookDirection.

(If you orient your head this way, you're looking out of the sphere along the normal, and your chin is pointing toward the target)

But we want the axes switched. So we compose this with a rotation that takes y+ to z+, and z+ to y-, namely Quaternion.AngleAxis(90f, Vector3.right)

(Continuing with the head analogy, this corresponds to tilting your head forward 90 degrees)

The result of composing these two rotations with * is a rotation that takes +y exactly to normal, and +z as close as possible to lookDirection.

I use this pattern so much, it might be worth adding it as an extension method to Quaternion, so you can get it with a single call, like Quaternion.LookRotationExactUp(forward, up)

\$\endgroup\$
1
\$\begingroup\$

(Posting my comment as an answer)

If you take the 3d plane for your cell and the line for that south pole, and find the intersection point, then you could use LookAt for that point.

You would also want to handle the case where the plane is parallel to that line, in which case you could rotate the plane to a predetermined angle, to orient it correctly.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.