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.