Wednesday, August 19, 2015

unity - Make object face another object on a sphere


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.



Answer



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.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...