- Home /
Read rotations around local axis
Hi! I'm new with Unity and I may need some help for a project.
In my work I need to get the angle of rotation of an object around one of its own axis. I know that EulerAngles gives me the rotation angles in world coordinates and localEulerAngles in parents coordinates. But i really need to know the angle of rotations in the object reference frame.
Is there a way? Thanks
Answer by WarmedxMints · Oct 05, 2019 at 01:18 PM
It sounds like you want to know how much it has rotated from its initial rotation. You could store the start rotation and then calc how much it has moved since, like so;
private Quaternion _referenceRot;
private void Start()
{
_referenceRot = transform.rotation;
}
private void Update()
{
Debug.Log(RotationOnAxis(1,transform.rotation * Quaternion.Inverse(_referenceRot)));
}
//axis 0 = x, 1 = y, 2 = z
private float RotationOnAxis(int axis, Quaternion rot)
{
rot.x /= rot.w;
rot.y /= rot.w;
rot.z /= rot.w;
rot.w = 1;
return 2.0f * Mathf.Rad2Deg * Mathf.Atan(rot[axis]);
}
Thanks! But still is not what I'm looking for! I see that it can be difficult to understand just from what i wrote so I'll make an example:
I have two cubes, one is parent and the other is child. Now I rotate the child of 45 degrees around its y axis and 30 degrees around its z axis. Now I can see that its localEulerAngles are (0,45,30), respect to parents axis.
If now I start rotating around the x axis of the child, of course all the localEulerAngles vary. What I want is to read that my child object has a rotation of 45 around its y and 30 around its z and tot. around its x.
I think it can be done using quaternions, but i don't know how to use them.
This one really helped me! Thank you, it was very useful! Which math is this based on? (Is it a rotation matrix?)
Answer by Bunny83 · Oct 05, 2019 at 12:48 PM
The way you have it worded at the moment doesn't make much sense. An object's position / rotation in it's own local reference frame is always 0,0,0 since that's what the local coordinates actually represent. So an object is always located at the local position 0,0,0 and has a rotation( euler angles ) of 0,0,0.
So what you want just makes no sense. I'm sure you actually want the rotation relative to some other reference space. However from your question it's not clear what that might be. You may want to draw yourself your coordinate system(s) on a piece of paper and just clear up for your self which angle you are interested in. So if you draw reference lines which angles you want to read.
Yes, you are right. I think I didn’t explain what I meant really well. When my object rotated along its own y axis I want to read that rotation because I need to use that angle. However, if I use localEuler angles, for example, the value I’m reading on the y value of that angle can vary even if I rotate along some other axis of the object because even a rotation along x and z axis of my object can produce a rotation around y axis of the parent.
So it is not the angle I’m looking for .
Answer by ZeBarba · Oct 06, 2019 at 08:42 PM
You want to use Quaternion.Angle
. This calculates the angles between to rotations.
As @WarmedxMints suggested, you will have to create a variable to store your reference rotation, and use Quaternion.Angle
to find the angle between your current rotation and last rotation.
But you will only get the "pure" euler angle of an axis if you do this between each rotation.
I created a sample scene to illustrate:
There are two cubes, one of them is a child to the other. The bottom one is the child.
The parent starts with a rotation in all axis.
After that, I rotate the child 45 degrees in y and 30 degrees in z, print on the console the eulerAngles and localEulerAngles, and store this rotation in a variable:
On the next step, I rotate the child 30 degress in x, and print the Quaternion.Angle result, and the euler angles (local and global).
Link: https://ibb.co/3d55MPF (there a limit for attachments)
As you can see, the Quaternion.Angle return the angle between the two rotations.
The thing is: this method allows you to find the angle one rotation at a time. If you do several rotations at once, this will not work.
Thanks, I'm not still sure is the best way, but it can be helpful
Answer by Dan1994 · Oct 06, 2019 at 10:24 PM
To be even more clear I'll explain my final purpose:
I have an object, let's call it controller, free to rotate around its axes. I have three more object and each one of them has to rotate around one of its axis.
When the controller rotates around its own X axis the first object rotates around its own X axis. When the controller rotates around its own Y axis the second object rotates around its own Y axis. When the controller rotates around its own Z axis the third object rotates around its own Z axis.
Each object has to move only with the rotation around the right axis and never with others. It's like I want to divide the transform.rotation of the controller in three different objects.
In that case, I would not parent any of them. Just put a script on the "main" one, with a reference to the 3 "little" ones. And something like this:
transform.rotation = transform.rotation * Quaternion(30,Vector3.right)
littleOne1.transform.rotation = littleOne1.transform.rotation * Quaternion(30.Vector3.rigth)
transform.rotation = transform.rotation * Quaternion(30,Vector3.up)
littleOne2.transform.rotation = littleOne2.transform.rotation * Quaternion(30.Vector3.up)
and so on. You manipulate the rotation with Quaternion.AngleAxis separately, in all algles for the main one, and just for one angle for the little ones.
Insted of 30 you put your input there.
Ok, but what if I don't know that "30" input? That's exactly the value I want to read from the controller!
One way is my answer post. Calculate the delta rotation of the main object each frame and apply it to the little objects, as respect to the axis you want to.
Any more than that, depends on your code. For instance, how is the main object rotating? Depending on it, you could do the same thing on the little ones, but only for one axis.
$$anonymous$$y last suggestion is: Stop using euler angles. Study and understand quaternions, it will make your life easier. Using Quaternions.AngleAxis, Quaternion.LookRotation, Quaternion.RotateTowards, and a good understanding of Vector Arithmetic (dot product, usage of normals, etc) can solve the vast majority of situations.
Your answer
