- Home /
How to check object "rotated" X degrees
Hello all,
What i want to learn is not "to rotate" but "to check" a local axis rotated degrees.
To clear the question a bit: I have a steering code based on rigidbody. When I start rotating the object ,i want it to stop, when the X (or -X) degrees have been achieved in one axis.
As i see euler angles are somewhat write only angles, and quaternion angles are a bit complicated for me to grasp.
Also angles are going from 0 to 180 but i want X to be infinite. Like i want to enter 780 and want to check if it completed the 780 degrees of rotation in one axis.
This is something i have been reading for some time but couldn't find a good way for this. If there is any link regarding this issue that would be great also.
Is the object being rotated by using torque, or are you manipulating the transform?
Using torque. the movement is based on physics and the input is controlled in another script by ai using 1 -1 simple inputs.
780 / 360 = 2.1, meaning if the user has turned the steering more than 2 times, the steering is probably broken. :P
But in general, if you want to monitor the rotation times, you can do it by euler angles itself,
angleChecker += transform.eulerAngles.y
if(angleChecker > 360 * i)
i++;
This is not going to accurately work, but the idea is every angle is a product of eulerAngles repeating them selves, so what you need to see is how many times has the user gone above 360 degrees, that is the "i" in the above code, useing the example you gave, when (angleChecker > 360 2), he is beyond 720 degrees, 360 2 is 720. and i is 2, meaning he has rotated the steering twice
Hence, i will get you the total rotations. euler's will reset (wrap) themselves when above 360, so you can monitor either 360's or 2 * 180 turns.
Sorry i am sure it is something i miss about how the euler angles are working.
The thing is the angle readings i get is pretty frantic. They never go from 0 to 360 (heck not even 0 to 180) The x is going from 359 to 270 than back to 359 And the other half is from 0 to 90.
Thank you very much for the help. This is the way to follow the rotation but maybe i should look the code a bit deeper to see what is causing this.
Is the behavior occurring based on the input? Or something you tried from above?
Answer by aldonaletto · Nov 16, 2013 at 05:32 AM
You should keep an auxiliary angle measurement, since reading Euler angles isn't reliable (as you already noticed). If you rotate only about X, things are easier: measure the angle between the current forward direction and the previous one, and accumulate it in the auxiliary angle variable. The angle can be measured with Vector3.Angle, but unfortunately this function always return a positive value - you must find its polarity with Vector3.Cross, like below:
private var lastFwd: Vector3;
private var curAngleX: float = 0;
function Start(){
lastFwd = transform.forward;
}
function Update(){
var curFwd = transform.forward;
// measure the angle rotated since last frame:
var ang = Vector3.Angle(curFwd, lastFwd);
if (ang > 0.01){ // if rotated a significant angle...
// fix angle sign...
if (Vector3.Cross(curFwd, lastFwd).x < 0) ang = -ang;
curAngleX += ang; // accumulate in curAngleX...
lastFwd = curFwd; // and update lastFwd
}
}
NOTE: Accumulating the angle over time may also accumulate small errors that eventually will become noticeable.
@aldonaletto - something similar was my first thought, but I assumed given the Rigidbody that he would have rotation on the 'y' and 'z' as well. If not, you code will work. But if he has arbitrary rotation, then it will fail. $$anonymous$$y fix for the problem was to move the vector into local space and then bring it onto the plane with the reference vector, but it did not work. I'm using transform.up as my reference vector. Thoughts?
private var prevUp : Vector3;
private var delta : float = 0.0;
function Start() {
prevUp = transform.up;
}
function Update () {
var v3 = transform.InverseTransformDirection(prevUp);
v3.x = 0;
var angle = Vector3.Angle(Vector3.up, v3);
var sign = (Vector3.Dot(v3, Vector3.forward) > 0.0f) ? -1.0f: 1.0f;
delta += sign*angle;
prevUp = transform.up;
transform.Rotate(Input.GetAxis("Vertical"), Input.GetAxis("Horizontal"), 0.0);
}
function OnGUI() {
GUI.Label(Rect(0,0,100,50), delta.ToString());
}
Thank you very much it works fantastically. @robertbu i haven't tested your solution yet but i will after i grasp the concept soon. thank you all for the answers.
Here i have converted aldonaletto's code to c# in case anyone need it.
using UnityEngine;
using System.Collections;
public class angleCalculator : $$anonymous$$onoBehaviour {
private Vector3 lastFwd;
private float curAngleX = 0;
void Start () {
lastFwd = transform.forward;
}
void Update () {
Vector3 curFwd = transform.forward;
// measure the angle rotated since last frame:
float ang = Vector3.Angle(curFwd, lastFwd);
if (ang > 0.01){ // if rotated a significant angle...
// fix angle sign...
if (Vector3.Cross(curFwd, lastFwd).x < 0) ang = -ang;
curAngleX += ang; // accumulate in curAngleX...
lastFwd = curFwd; // and update lastFwd
}
print (curAngleX);
}
}
@robertbu, that's a good and very elegant idea. I tested it, and at first everything worked fine - at least when rotating one axis at a time. When rotating both axes at the same time, however, the angle informed became a lot below the expected value. I suppose that this happens because when you rotate about X and Y in the same Rotate, the object first rotates about X, then about its new local Y; when the previous up vector is flattened onto the new X plane, the angle measured is lower than what it actually rotated. A possible solution would be to convert the new up to the previous local space, what seems a lot more complicated (the previous worldToLocal matrix or rotation should be saved ins$$anonymous$$d of the up direction). Anyway, when rotating about multiple axes it's hard to define how the local angle rotation must be measured. I think that your way is perfectly good for most cases, since it doesn't depend on the world axes like $$anonymous$$e.
Your answer
Follow this Question
Related Questions
Quick Angles Question 2 Answers
Getting cosinus of an angle in degrees 3 Answers
Clamp rotation of sprite? 0 Answers
Trying to get the angle of a camera object based on players forward, is not distance independent 0 Answers
Help with gun accuracy in degrees. 3 Answers