- Home /
Correcting Quaternion.FromToRotation sometimes being flipped
I am having trouble fixing Quaternion.FromToRotation when the rotation result is sometimes upside down. I "think" I understand the principles of why, but I couldn't find a decent explanation on how to solve the problem for my use case. Most of the supplied answers I found usually recommended you use Quaternion.LookRotation instead, but I can't do that, as I am also moving the object to a new point at the same time.
Essentially, I am trying to "snap" a race track piece on the end of an existing piece. The object has child objects which are the connection points, when two of these touch (using a trigger) then the track piece is snapped so the child connection points touch (but are facing the opposite direction). The code I am using works in "most" cases, but seems to trip up when dealing with angles that aren't 45 or 90 degrees? I've tried various fixes, and nothing seems to make it consistent 100% of the time.
This is the code I use to snap the track piece on the end of the other piece:
public void MoveToPoint(ConnectionPoint connectionFromPoint, ConnectionPoint connectionToPoint, bool opposite)
{
// Flip the rotation if we are snapping to a connection (not attachment) point
Quaternion fromToRotation = Quaternion.FromToRotation(connectionFromPoint.transform.forward, connectionToPoint.transform.forward);
if (opposite) fromToRotation = Quaternion.FromToRotation(connectionFromPoint.transform.forward, -connectionToPoint.transform.forward);
tr.rotation *= fromToRotation;
// Set the rotation again, using the up direction, as sometimes FromToRotation can give an upside-down result
tr.rotation = Quaternion.LookRotation(tr.forward, connectionToPoint.transform.up);
// Finally calculate the target move from to position, rotating the location position offset into our prop space
Vector3 localPositionScaled = Vector3.Scale(tr.localScale, connectionFromPoint.transform.localPosition);
Vector3 position = connectionToPoint.transform.position - (tr.rotation * localPositionScaled);
tr.position = position;
}
Here is a picture of a track piece with those connection points:
Your answer
Follow this Question
Related Questions
Get slerp to work just as LookAt(,Vector3.right) does 1 Answer
Ellipse Animation by code 2 Answers
How to use quaternion.lerp 2 Answers