Hi All
I have just started using Unity for a thesis project. I have some programming background but no real 3D understanding so please bear with me. What i have done so far:
- Created a UV FLipped sphere from Blender and imported it into Unity.
- I am using this sphere to display a 360 video
- I have a Camera object in the sphere which i am using with an Oculus Rift DK 2 to allow the someone to view the 360 video
So far the above works well. I have attached a script to the camera object to write the camera rotation information to a file. I am using this to track head movement. The script works in that it writes the relevant information to the file. The problem i am having relates to the X rotation values being written. I am using the following to get the rotation:
Float headX = Mathf.Round(head.eulerAngles.x);
What this returns is the rotation in euler angles, but it only returns a range between 270 - 360 or between 0 - 90, depending where i am looking. So for example, when i look straight ahead it returns 0, if i then look up it returns values starting at 360 moving down to 270. Once it gets to 270 i am looking directly up. So far so good. But if i carry on rotating the oculus past 270 it then starts returning values starting at 270 going back up the scale to 360. Similarly, if i start looking down the X value starts a 0 and runs through 90, and if i rotate through 90 it goes back down through the scale to 0.
I have read posts that using the below code will return what is in the Transform inspector window, but again it doesnt. It seems to return the same as what i mentioned above, values ranging between 270 - 360 and 0 - 90.
Transform.localRotation.eulerAngles.x
This is the main function i am using to set everything.
//Assigned to the main game object
public Transform body;
//Assigned to the camera object
public Transform head;
// Holds last frame's head rotation to compute frame-to-frame velocity:
public static Vector3 m_lastHeadRotation;
//Assigned to the main camera
public Camera cams;
//Float variable Vertical Field of View in radians
public static float vFovInRads;
//Float variable Vertical Field of View in degrees
public static float vFov;
//Float variable Horizontal Field of View in radians
public static float hFovInRads;
//Float variable Horizontal Field of View in degrees
public static float hFov;
//Float camera height
public static float cameraHeightAt1;
//Float to hold head X
public static float headX;
//FLoat to hold head Y
public static float headY;
//FLoat to hold last headX
public static float lastHeadX;
//FLoat to hold last headY
public static float lastHeadY;
//Used at a fixed interval of 0.02 seconds
void FixedUpdate(){
//setting the last head X position and cast to a float
lastHeadX = Mathf.Round((float)(m_lastHeadRotation.x));
//setting the last head X position and cast to a float
lastHeadY = Mathf.Round((float)(m_lastHeadRotation.y));
//setting the current head X position
headX = Mathf.Round(head.eulerAngles.x);
//setting the current head Y position
headY = Mathf.Round(head.eulerAngles.y);
//Call function to write to file
WriteFrameData (head, headX, headY, lastHeadX, lastHeadY);
//Set current position to be used when fixed update is called again
m_lastHeadRotation = head.localRotation.eulerAngles;
}
What am i doing wrong here, how do i get the rotation as displayed in the Transform inspector?
Thanks for the help.
The problem is that you are considering only the x component of a rotation in isolation, and that there are many possible sets of Euler angles that can all describe the same rotation.
Consider your example of “carrying on rotating past 270” (looking straight up, and then carrying on tilting back another 10 degrees, say). You could get to that position by looking straight ahead and tilting back over your head (as you are doing), which would give a rotation of something like (260, 0, 0) which I think is what you are expecting. However you could also get exactly the same rotation by first turning around to face backwards, then tilting your head up to slightly less than straight up. You’d also have to crane your neck around to make things the same way up, i.e. (280, 180, 180).
These two sets of euler Angles describe exactly the same rotation. The reason you don’t see the 90> x < 270 in your logs is because you’re not considering the other axes that describe the rotation.
Thanks for the response @Tanoshimi. Sorry for my late reply, i work full time and am finishing my Masters part time. I think i understand what you are saying. Unfortunately my 3D spatial maths is not that advanced, i am a Psychology student using VR for a thesis project. So is there a standard function / method to transform the X value to a 360 degree value? Similarly is there the same thing for the Y? My idea is to use almost a “Cartesian” type mapping system to understand what part of the sphere someone is looking at. SO if the participant rotates left by 20 degrees and looks up 60 degrees i could use these points to mark a point on the sphere. In my code i can deduce when someone looks up, down, left right. But i cant identify if they looked past 270 degrees or past 90 degrees.
//This function is used to write all the data to the text file
//X axis looks at pitch - head looking up or down
//Y axis looks at yaw - head looking left or right
//Z axis looks at roll - head tilting side to side
static void WriteFrameData(Transform head){
SW.WriteLine ("----------------------Camera Rotation Data----------------------");
//Write the X co-ordinates
SW.WriteLine ("Head Rotation X: " + head.eulerAngles.x);
//Check to see which way the head moved on the X axis
if (((m_lastHeadRotation.x) - (head.eulerAngles.x)) > 0) {
SW.WriteLine ("Head Rotation Velocity X: Look Up");
} else if (((m_lastHeadRotation.x) - (head.eulerAngles.x)) < 0) {
SW.WriteLine ("Head Rotation Velocity X: Look Down");
} else {
SW.WriteLine ("Head Rotation Velocity X: No Change");
}
//Write the Y co-ordinates
SW.WriteLine ("Head Rotation y: " + head.eulerAngles.y);
//Check to see which way the head moved on the Y axis
if (((m_lastHeadRotation.y) - (head.eulerAngles.y)) > 0) {
SW.WriteLine ("Head Rotation Velocity Y: Look Left");
} else if (((m_lastHeadRotation.y) - (head.eulerAngles.y)) < 0) {
SW.WriteLine ("Head Rotation Velocity Y: Look Right");
} else {
SW.WriteLine ("Head Rotation Velocity Y: No Change");
}
//Write the Z co-ordinates
SW.WriteLine ("Head Rotation z: " + head.eulerAngles.z);
//Check to see which way the head moved on the Z axis
if (((m_lastHeadRotation.z) - (head.eulerAngles.z)) > 0) {
SW.WriteLine ("Head Rotation Velocity Z: Tilt Right");
} else if (((m_lastHeadRotation.z) - (head.eulerAngles.z)) < 0){
SW.WriteLine ("Head Rotation Velocity Z: Tilt Left");
} else{
SW.WriteLine ("Head Rotation Velocity Z: No Change");
}
hi, has anyone else come across this problem. i saw the reply saying that there are a lot of different ways for euler angles to get to the same position, but i created a ui to display the euler agles of a rotating body, and this only happens on the x axis. if you do exactly the same thing with the y and z axis ( rotate an object with rigidbody.addtorque), the euler angle values go right round from 1 to 360 and then back to zero, but with x axis , as the originator of this thread correctly said, the angles display exactly as describes above, going from 0-90, then back from 90-0, then 270-360, and then back from 360 to 270. they completely miss out the value range 90-270, no matter what you do. immy case i want one object to copy the x axis rotation of another object, which works perfectly on the y and z axis, but for the reasons describes above, is not possible on the x axis, and is obviously not supposed to work that way.
i think this is a bug. @gomensa @tanoshimi