Giving Vertices a Rotation
I have paths, each of which contains a list of vertices. At present they are being used for turrets that can move along the path. In order for them to work correctly they need to not only get their current position from a point along the path, but also their rotation.
Simply setting the turret's forward axis to be towards the next vertex is insufficient because that does not create a distinction between (for example) a circular path on a wall and a circular path around an object. I therefore need to calculate a rotation for which the forward axis points towards the next vertex and the up axis points towards something that I can specify. My intention is to store an "up" rotation for each vertex and lerp between them when the turret is between two vertices.
I have been beating my head against this problem for a week. First I used quaternions and couldn't make that work, then switched to a system that simply specified a float "rotation angle" which would be applied around the forward axis after creating a quaternion facing the next vertex. This can be made to work in a rather clunky way, but then once the path moves in world space (for example if the path sits on an asteroid or is mounted on a ship) it all breaks completely. I know there is a solution involving quaternions, but either I have missed it or it is beyond me, and I would appreciate any assistance.
Answer by nintendoeats · Aug 18, 2017 at 09:33 PM
Agh! I did it! I literally had to try 15 different things over the course of at least a week, but I did it!
Vector2 lookingAdjustment =
Vector2.Lerp (vertices [lowerVertex].normal, vertices[upperVertex].normal, requestedPointBetweenBoundingPoints).normalized;
Quaternion finalRotation = Quaternion.identity;
finalRotation.SetLookRotation(getFacingVectorFromVertex(lowerVertex).normalized,(Vector3) lookingAdjustment);
return finalRotation;
PathVertex.normal is a Vector2 that is constrained to magnitude 1. This function produces the LOCAL rotation, as the name says. A world-relative rotation is then created like this:
turret.transform.rotation = path.transform.rotation * path.GetLocalNormalOfPathAtPoint (pathPosition);
It just took a few more hours of doing something else and I FINALLY got it. I hope this is useful to somebody else.