- Home /
Angles from quaternion/vector Problem.
I need to get the negative and positive angle from the current facing direction on the y axis/or x of the player and where the gun is aiming... and then make it do something if that angle is bigger than a certain degrees within 180 degrees.
My code is just not working out, and I need to get it on the specific axis too... HELP!
Here is the code as far as I could get:
// The current rotation of the player.
playerRotation = player.rotation;
//The weapon/gun look at target.
weapon.LookAt(target.position);
// The rotation of the weapon.// From this point onwards is where I mess up.
Quaternion wpRot = weapon.rotation;
//Get angle between player rotation and weapon rotation.
float wpRotAngle = Quaternion.Angle(playerRotation, wpRot);
if(wpRotAngle > 45){
// do something....
}
You can get the signed angle between two vectors or even rotations in a couple of different ways. But it is unclear to me what solution to give you. Can you explain a bit more about what "do something..." is?
Answer by HideAndSeek · Mar 20, 2016 at 04:31 PM
This answer might be a little late, but in case anyone needs it:
If you are searching for the signed angle between two quaternions where you know the axis of rotation (since signed angles without known rotation axis make no sense) and assuming you actually only rotate around that arbitrary but specific axis, you can simply do the following:
Compute the Quaternion.ToAngleAxis of your current rotation that gives you the unsigned angle and the rotation axis in world space
Compute the Vector3.Angle between your known "axisOfRotation" (given in world space) and the computed rotation axis by Quaternion.ToAngleAxis
If Vector3.Angle is greater than 90° (usually 180°), you know that the computed axis by Quaternion.ToAngleAxis points the other way around.
Normalize the angle again to [-180,180] since one quaternion rotation cycle contains 720° (for example, from (1,0,0) to (-1,0,0))
Simple as that :) Here goes the code:
public static float GetSignedAngle(Quaternion A, Quaternion B, Vector3 axis) {
float angle = 0f;
Vector3 angleAxis = Vector3.zero;
(B*Quaternion.Inverse(A)).ToAngleAxis(out angle, out angleAxis);
if(Vector3.Angle(axis, angleAxis) > 90f) {
angle = -angle;
}
return Mathf.DeltaAngle(0f, angle);
}
Hope this works for anyone who reads this in future :)
Note again: This code really assumes that you actually only rotate around the axis of rotation! Otherwise, the computed angle might not be correct anymore.
Cheers!
This is working like a charm and exactly what i needed. Thanks HideAndSeek
$$anonymous$$an, yout little function solved my problem perfectly. Thanks a lot dude :D
Answer by KellyThomas · Dec 18, 2013 at 04:39 PM
Quaternion.Angle will return the smallest angle connecting to two rotations with no regard to axes. The number will be in the range: 0
If you want the signed angles for each axes the you need to convert your rotations to euler angles:
private Vector3 EulerAnglesBetween(Quaternion from, Quaternion to) {
Vector3 delta = to.eulerAngles - from.eulerAngles;
if (delta.x > 180)
delta.x -= 360;
else if (delta.x < -180)
delta.x += 360;
if (delta.y > 180)
delta.y -= 360;
else if (delta.y < -180)
delta.y += 360;
if (delta.z > 180)
delta.z -= 360;
else if (delta.z < -180)
delta.z += 360;
return delta;
}
This starts with a simple difference then corrects the results to compensate for those cases when the smallest angle crosses the 0 degree / 360 degree threshold.
Each component of the Vector3 will be in the range: -180
Ok I'm a little lost with what just did... But I managed to get half of it to work.
The only thing now is to get it to read then negative angle. So far it just detects the size regardless.
playerRotation = player.rotation;
weapon.LookAt(target.position);
Quaternion wpRot = weapon.rotation;
Vector3 delta = wpRot.eulerAngles - playerRot.eulerAngles;
if(delta.y >) 90){
//Do something.
}
// I need to separate the direction. As in -90 to the left and 90 to the right.
//Hope you understand what I mean.
Thanks so far. Sorry for noobness.