0
\$\begingroup\$

I have a game I'm working on in Unity where there are two objects on a sphere at random locations (and random rotations). I want one of the objects to always rotate so that if it were to fire a bullet (the end goal) that it would fire at the other object along the shortest arc around the sphere.

The problem I'm facing is that I don't know how to create a rotation for an object that is on the surface of a sphere, and have it point towards the other object.

I can also see an issue after this where I would need it to point towards the other object in the shortest distance because there will always be two directions it can point towards.

Has anyone done something like this? Definitely stuck on this one.

\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

This can be done more simply than it might appear.

We can think of this as an orientation that points our local y+ (up) axis directly outward from the sphere, so our local xz plane is tangent to the sphere at our position, and points our local z+ (forward) axis in the direction of the target projected onto this plane.

Unity already has a method to construct a rotation that matches one axis exactly, and the second as close as possible with the remaining degree of freedom: Quaternion.LookRotation. But it wants to point z+ exactly and y+ as close as possible, so we just need an extra twist to exchange the axes.

// Compute vectors from the center to each object.
Vector3 toMe = transform.position - sphereCenterPosition;    
Vector3 toTarget = target.transform.position - sphereCenterPosition;

// Form a rotation that points z+ exactly out from the sphere,
// and y+ away from the target in the remaining degree of freedom.
Quaternion pointOut = Quaternion.LookRotation(toMe, -toTarget);

// Twist this rotation 90 degrees about the local x axis,
// so now y+ points out from the sphere, and z+ points toward
// the target within the remaining degree of freedom.
Quaternion pointOnShortestArc = pointOut * Quaternion.Euler(90, 0, 0);

I can't recall whether LookRotation gracefully handles the case where the two axes are parallel (meaning the targets are on the same/opposite poles and the direction we shoot doesn't matter, so we can pick one arbitrarily), but if it acts up we can detect this case and provide a fallback behaviour.

\$\endgroup\$
6
  • \$\begingroup\$ Ok, so I think this is close... It's still not shooting in the correct direction, but it's better haha. I think this is my lack of knowledge with Quaternions. I need to get a normalized direction vector from this in the end (which I can combine with my velocity to generate movement in that direction). I use a pivot point at the sphere center to rotate in a direction, which causes a child of the pivot point to orbit at a set distance from the sphere center. This is how the bullets travel spherically. \$\endgroup\$
    – DRiFTy
    Commented Dec 30, 2017 at 16:31
  • \$\begingroup\$ The rotation axis for the bullet will be pointOnShortestArc * Vector3.right, if that's what you're asking. If you're looking for something else, I'll need more details than "not yet correct" \$\endgroup\$
    – DMGregory
    Commented Dec 30, 2017 at 16:34
  • \$\begingroup\$ Bingo. You're a life saver. That was it (aside from normalizing the rotation axis). Thank you! \$\endgroup\$
    – DRiFTy
    Commented Dec 30, 2017 at 16:40
  • \$\begingroup\$ Do you have any insight as to why when these two objects pass 180 degrees around the sphere that the rotation axis seems to be mirrored? This only seems to be an issue when both objects are on that half of the sphere. \$\endgroup\$
    – DRiFTy
    Commented Dec 30, 2017 at 16:48
  • \$\begingroup\$ It shouldn't be. Unity uses a left-handed coordinate system. Put your left hand in front of you and point the thumb to your right to act as your bullet rotation axis. The fingers of your left hand curl away from you and down: that's the direction a positive rotation about that axis will travel, and it matches what we want our bullet to do. So unless you're computing your bullet rotation angles differently based on position, this should always be what we want. Try posting a new question detailing how you're firing your bullet now and we can diagnose it in more depth. \$\endgroup\$
    – DMGregory
    Commented Dec 30, 2017 at 17:09

You must log in to answer this question.

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