- Home /
Axis-clamping a transform rotated with a Quaternion
The goal is to clamp the turret transform so that it can only rotate around the Y axis, providing for horizontal-only turret rotation.
First, my code so far:
var turret: Transform;
var barrel: Transform;
function Update () {
// Get the Vector3 of where the camera is looking
var aimpoint : Vector3 = camera.ViewportToWorldPoint(Vector3(.5,.5,250));
// Clamp the turret's rotation
// ????
// Get the raw rotation and feed it to the turret
turret.transform.rotation = Quaternion.FromToRotation(Vector3.forward,aimpoint);
}
In this circumstance, the script is being run from a camera which orbits the turret. The camera is also a child of the turret.
What I am trying to do is cause the turret to transform in such a manner as to point at the same location as is given by the camera.ViewportToWorldPoint function passed from the center of the camera.
The script works a little too well as the turret transform rotates to face the aimpoint on all axes.
I have been looking for a way to clamp the transform so that it can only pivot on the Y axis (horizontal rotation only), however I'm having no success at it. I have tried various combinations of Vector3 and Mathf.Clamp but can't seen to make it work.
It has also occurred to me that I may be able to pass only a particular axis from camera.ViewportToWorldPoint to the variable which then gets passed to Quaternion.FromToRotation, but I have no idea how to do that.
Any help would be greatly appreciated.
NOTE: Edits are to attempt to fix the code not being displayed correctly in the final question.
Answer by Owen-Reynolds · Mar 10, 2012 at 06:44 PM
Can use the same trick to make a person Y-rotate to face the target, but not tilt back/forwards. Adjust the target to be at your height:
Vector3 aimPoint = .... ScreenToWorld(...); // NOTE: in world coords
aimPoint.y = turret.y; // <--so lazy hack, but common, easy and obvious
turret.LookAt(aimPoint);
// NOTE: lookAt is a shortcut for the lookRotation below:
turret.rotation = Quaternion.LookRotation(aimPoint-turret.position);
// NOTE: LookRotation is FromToRotation with From set at forward
Thanks for the quick reply and pardon my noobishness.
I was recalled to work early this evening so I didn't get a chance to look at it before I had to leave. When I get home I'll sit down with it for a few $$anonymous$$utes and make sure it works.
I'm amazed that the solution can be so simple. If I'm reading it right, Quaternion gets passed only the y axis, which is excellent.
If it's not too much trouble, how would I search for the function/constructor/whateveritmaybe which allows for only passing the y (or x or z I'm assu$$anonymous$$g) coord from a variable containing a Vector3?
The scripting reference has all the built-in functions. Runtime functions gives you this: http://unity3d.com/support/documentation/ScriptReference/20_class_hierarchy.html and then, selecting any of them also gives you a nicer list down the left side.
In theory, you'd use a Vector2 to store just x and z for "top down" coords. But then you have to remember that v2.y
is really v3.z
, which usally causes trouble, so people use V3's and hack the y to "not count."
Your solution worked like a champ.
I tried the v2 bit before I asked the question, trying to get "top down" and it caused all manner of issues, now I know why.
Despite looking at the reference a good bit, for some reason I glossed over the .x/.y/.z portions.
Next step is to make a rotation of a similar manner which has a top speed, should be relatively simple now.
Thanks again for the help, it's greatly appreciated.