I am currently really confused regarding how rotation (and eulerAngles) work in Unity, and I feel like I am missing something fundamental.
I have a game object Emma
, which has a script that constantly prints out the rotation (mainObject
points to the Emma
object):
"emma1 x=" this.transform.eulerAngles.x " y=" this.transform.eulerAngles.y " z=" this.transform.eulerAngles.z);
"emma2 x=" mainObject.transform.rotation.eulerAngles.x " y=" mainObject.transform.rotation.eulerAngles.y " z=" mainObject.transform.rotation.eulerAngles.z);
"emma3 x=" mainObject.transform.rotation.x " y=" mainObject.transform.rotation.y " z=" mainObject.transform.rotation.z);
"emma4 x=" mainObject.transform.localEulerAngles.x " y=" mainObject.transform.localEulerAngles.y " z=" mainObject.transform.localEulerAngles.z);
In the editor, I have rotated Emma
to x=235 y=20 z=70
.
However, the output becomes x=305 y=200 z=250
.
Regardless how I rotate Emma
the editor values makes sense for me, but the print output is understandable for me.
Another example is editor x=250 y=180 z=100
but the output becomes x=290 y=5 z=280
.
Even if I rotate one axis in the editor, for example x
in the script, all 3 can change (x, z, y
) which makes no sense to me.
My fundamental problem is; I want, via scripting, be able to rotate Emma towards a specific direction (like towards a door in the flat). I can figure out the values by rotating Emma in the editor, but if I am not able to apply those values via scripting, then how else would one do it.
So my questions are:
- Why do they differ? I read somewhere that the editor shows the
localEulerAngles
but apparently this is not true. - How do I print in a script the values that are shown in the editor? Am I not using the correct functions?
- If I want a specific direction shown in the editor, what functions should I be using to set that rotation?
CodePudding user response:
The problem is that you're trying to find a direct correlation between EulerAngler and Quaternions, which will not work. Just to clarify, what you see in the editor is your localEulerAngle, and maybe you are asking, "if localEulerAngles is the value shown in the editor why do they differ in my code", this happens because eulerAngles does not store the X, Y, Z info, the property that you access through your code is a representation of your quaternion as angle, but the editor store the values that you insert there, and internally convert those values to a quaternion, you can read more about it in documentation https://docs.unity3d.com/ScriptReference/Transform-localEulerAngles.html
Hope this help
CodePudding user response:
After trying to make sense of this, I have personally come to this conclusion:
There is no straightforward mapping between the editor's X/Y/Z
rotation values and .transform.rotation.eulerAngles.x/y/z
values.
For example, .transform.rotation.eulerAngles.y
keep changing even though, I might not have modified it, because of Unity's internal handling of rotations, meaning it is not a good way to answer the question "What Y rotation does this object have?".
My solution
In order to abstract away Unit's own (magical) logic, I have created my own Single Source of Truth by creating my own variables on moving objects.
Simplified implementation:
public class Emma : MonoBehaviour
{
private float currentRotX = 0;
private float currentRotY = 0;
private float currentRotZ = 0;
void Update() {
transform.eulerAngles = new Vector3(currentRotX , currentRotY, currentRotZ);
// or
transform.rotation = Quaternion.Euler(new Vector3(currentRotX , currentRotY, currentRotZ));
}
}
Meaning, if I want my object to have a specific rotation, I assign my own variables:
void lookAtDoor(){
this.currentRotX = 123;
}
and If I want to know what rotation my object currently has, it would be:
boolean isLookingAtTV(){
return this.currentRotX == 123;
}
Meaning, I have creating my own Single Source of Truth abstraction layer on top of however Unity wants to do it.
This has saved me a lot of headache and I hope this pattern helps the next person reading this!