- Home /
LookAt whilst traversing a sphere
Hi,
I have a situation where I have an object that is on a sphere. Imagine the red dot is the object, and the green dot is where the object is facing.
I have code in place to allow the player to click on a point on the sphere and the object will move there. I now want the object to be facing the direction that it is moving. Initially I just went with:
object.LookAt(vecNextPointInPath)
However, this makes the object tilt in weird ways as it moves. I want to make sure that the top of the object is always facing upwards of the sphere as well as this LookAt. I am able to make it do this, by setting
transform.up = transform.position
however when I do this in tandem with the LookAt, the LookAt seems to be stomped over and it stays facing the same direction no matter which direction it is moving.
Does anyone have a solution to this? I imagine there is something with maths/quaternions that I've not figured out yet.
Thanks.
Answer by Namey5 · May 04, 2020 at 12:40 PM
You can use vector projection to find a direction perpendicular to one vector in the direction of another (which, in this case when used as the look direction of the object, would align said object with the surface of the sphere).
//Where 'spherePos' is the centre of the sphere and 'targetPos' is the world-space position of the look target
Vector3 up = (transform.position - spherePos).normalized;
//'targetDir' is just the vector of the target position from the sphere - use whatever you already have here, just make sure it's normalized
Vector3 targetDir = (targetPos - spherePos).normalized;
//Use the dot product to project the two vectors
Vector3 forward = targetDir - up * Vector3.Dot (targetDir, up);
//Find the relative quaternion and set it as our rotation
transform.rotation = Quaternion.LookRotation (forward.normalized);
Thank you! I'd made a couple of modifications (sphere is always at 0,0,0, and I think you missed the up vector in the final line of code, so I now have this:
Vector3 up = m_transform.position.normalized;
Vector3 targetDir = nextPosition.normalized;
Vector3 forward = targetDir - up * Vector3.Dot(targetDir, up);
m_transform.rotation = Quaternion.LookRotation(forward.normalized, up.normalized);
and that works perfectly!
Good point. I was using a capsule for testing, so the up axis didn't make any visual difference. There's also probably no need to normalize the vectors in the quaternion constructor (up is already normalized and even though I did it for forward in the original, I don't believe magnitude makes a difference to quaternions).
Answer by JonPQ · May 04, 2020 at 07:01 PM
you can use transform.lookat and specify the up vector for which axis to rotate around. your up vector is the vector position of the object minus the center of the sphere's position... https://docs.unity3d.com/ScriptReference/Transform.LookAt.html