# [SOLVED] How to get "Rotation" value that is in the inspector?

Discussion in 'Scripting' started by AlanMattano, Mar 10, 2017.

Not open for further replies.
1. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
Is there a direct way to get the value that are in the Rotation field of the inspector?
I need that angle that is in the inspector. for example Transform > Rotation (X)

It can be the local or world but i need the same value.
I try :

Code (CSharp):
1. float angleX = myTransformGO.rotation.x;
go from 0 to 0.5 and go down with same signe.

Code (CSharp):
1. float angleX = myTransformGO.rotation.eulerAngles.x;
but the values are not the same. If i go negative go over 270 with no sign.

So is difficult to make the math. I try variants and manual.

Is there a direct way to get the value that are in the Rotation field of the inspector?

Solution:

Code (CSharp):
1.
2.
3.     [SerializeField]
4.     float eulerAngX;
5.     [SerializeField]
6.     float eulerAngY;
7.     [SerializeField]
8.     float eulerAngZ;
9.
10.     void Update()
11.     {
12.         eulerAngX = transform.localEulerAngles.x;
13.         eulerAngY = transform.localEulerAngles.y;
14.         eulerAngZ = transform.localEulerAngles.z;
15.
17.         // ...if ( eulerAngX  > 180f) ... code go here...[/B]
18.
19.         /* Get X    [ ATT: SIMILAR TO THIS  EXAMPLE  ]
20.
21.         if (  eulerAngY  > 180f)
22.           {
23.               if (  eulerAngX  > 256f)
24.                   xAngle = ( eulerAngX  *-1f) +360f;
25.               else
26.                   xAngle= - eulerAngX;
27.           } else {
28.
29.               if (  eulerAngX  > 256f)
30.                   xAngle=  eulerAngX  - 180f;
31.               else
32.                   xAngle= (( eulerAngX  * -1f) + 180f) * -1f;
33.           }
34. */
35.
36. }
37.

Could anybody write an answer about how to calculate it like Unity does?

HERE IS A LINK TO A BEAUTIFUL MANUAL

Last edited: Jan 26, 2019
SrDidE, PastequeBuild, ow3n and 2 others like this.
2. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
No. The Inspector numbers are specially tweaked away from the code values, to look nice for humans. They depend on the starting Inspector values. Put (000) in the Inspector and run some code. Then put (360,360,-360), which is the same as 000, and run the same code. The numbers you see will be different.

The code values you get are always 0-360. If you really want to use raw eulerAngle x,y,z, it's probably best to rely on that. Maybe if you start the Inspector at (180,180,180), you'll see the same (never tested.)

The longer version of this is near the end of the rotations chapter in taxesforcatses-dot-com, but's it's just more examples and details.

3. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
I really really need the inspector values for human reasons. [VOTE HERE]
I wish that "transform.Rotation" returns the values is in the inspector. With capital "R". Last edited: Mar 12, 2017
vonSchlank and bon1254 like this.
4. ### JoshuaMcKenzie

Joined:
Jun 20, 2015
Posts:
884
transform.rotation.x is a complex number. its not a angle and oscillates from -1 to 1. same goes for y,z,and w components
as for converting to +/- 180:
Code (CSharp):
1.
2.         private static float WrapAngle(float angle)
3.         {
4.             angle%=360;
5.             if(angle >180)
6.                 return angle - 360;
7.
8.             return angle;
9.         }
10.
11.         private static float UnwrapAngle(float angle)
12.         {
13.             if(angle >=0)
14.                 return angle;
15.
16.             angle = -angle%360;
17.
18.             return 360-angle;
19.         }
so WrapAngle will convert 270 to -90

oAzuehT, Shadden120, FunSTW and 23 others like this.
5. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
So how do I use this 2 functions? I pass them the "transform.rotation.x" oscillation or the Euler angle?

6. ### joshuaflash

Joined:
Oct 27, 2015
Posts:
14
Your best bet is probably writing your own Rotations script using [SerlializeField] with private variables that read the eulerAgles. Update the values using [ExecuteInEditMode] and you will be able to see the corresponding values in the inspector on your Rotations script. They won't be the same as the values seen in transform, but they should satisfy your human reasons ;-)

https://docs.unity3d.com/ScriptReference/ExecuteInEditMode.html

AlanMattano likes this.
7. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
You mean by accuracy? In any case I need the value for my game. I'm not an expert but if i use [ExecuteInEditMode] It will be included into the build?

8. ### joshuaflash

Joined:
Oct 27, 2015
Posts:
14 Sort of like this. They might differ by 360, but you can see them update. If you just use these instead of the values shown in the transform component, you can manipulate them for your game using only the localEulerAngles.

Code (CSharp):
1. [ExecuteInEditMode]
2. public class EnableDTScript : MonoBehaviour {
3.
4.
5.     [SerializeField]
6.     float eulerAngX;
7.     [SerializeField]
8.     float eulerAngY;
9.     [SerializeField]
10.     float eulerAngZ;
11.
12.
13.     void Update() {
14.
15.         eulerAngX = transform.localEulerAngles.x;
16.         eulerAngY = transform.localEulerAngles.y;
17.         eulerAngZ = transform.localEulerAngles.z;
18.
19.     }
20. }

9. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
I do not need to manipulate them. Yes I had multiple manipulations of them. And at the end, I need the angle of incidence that is exactly what is in the inspector!
But looks like there is no direct way to GET the inspector value. After you make a lot of manipulations to an object (for example using look at) the object quaternion has arbitrary orientation. In the case that arbitrary orientation is fix , then is possible to get the angles by using if statement for each quarter of the 360. And making same math to each value you get the value that is in the inspector. What bothers me is that I can look to the value that is ready for me in the inspector but I'm not able to use it in any way. [FEEDBACK VOTE LINK]

Last edited: Mar 11, 2017
10. ### LaneFox

Joined:
Jun 29, 2011
Posts:
7,290
Look, rotations are handled by Quaternions. If you're doing anything with rotations you need to be familiar with at least Quaternion.Euler(Vector3 input) and the fact that the inspector values are just an euler version of the Quaterion that is in reality the real rotation value of some object. There are many euler ways to represent the same exact Quaternion value, so you can have stuff like (0,0,0) also perfectly equal to (360,-360,-360). That applies to eulers as well, but Quats of course hit more niche values and hopefully you see the point.

You can basically get anything you want in euler values by doing Quaterion.Euler(). If you want to manipulate rotations with euler values, do it with Quaterion.Euler(). If you want to use Euler values, manipulate the rotation of a transform with Quaternion.Euler().

Don't get your hopes up. You're asking for something that on a technical level is a non-issue because a little understanding of the context reveals that you can easily use the currently exposed values to accomplish what you're asking.

Last edited: Mar 11, 2017
Olipool and AlanMattano like this.
11. ### JoshuaMcKenzie

Joined:
Jun 20, 2015
Posts:
884
I don't know what everyone keeps talking about. The fact that multiple angles can represent the same Quaternion doesn't matter, its moot and irrelevant to the OP. which angles that get represented in a Vector3 depends on the rotation order specified. and pretty much everything in unity defaults to the same rotation order, the Transform inspector included. and this is why that fact is irrelevant.

The Transform inspector is simply displaying the local euler angles in the order of ZXY. transform.localEulerAngles will return the same values. This is because ZXY is the default order in Unity for any rotation represented as a Vector3. This includes transform.eulerangles, transform.Rotate (which mentions this in its documentation), and Quaternion.eulerAngles.

Alan just wants to read out the same angles that the inspector displays. He doesn't have to worry about gimble lock or any special properties revolving around Quaternions. Just use transform.localEulerAngles and be done with it.

as said before. transform.rotation is a Quaternion and the Quaternion components (x,y,z,w) are NOT angles they are complex numbers. unless you understand the math behind Quaterions leave these variables alone. Now Quaternions isn't rocket science, its just an expansion of high school math. Remember imaginary numbers (square root of -1)? Quaternions is just the 3D version of imaginary numbers.Simply put they are not the variables you want.

you will want to use UnwrapAngle(transform.localEulerAngles.x); You'll get an angle of x that ranges from -180 to +180.

Slycodger, zeiksz, Kupferrot and 7 others like this.
12. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
The problem is it doesn't -- eulerAngles and what the Inspector shows are not the same. Of course, they're the same angle, but not the same numbers.

The Inspector saves your original hand-entered values. Then it takes the real eulerAngles and adjusts them to keep the Inspector as close to those starting values as possible -- using either +/-360 or flipping x (the "over the top" problem.) You can see this -- enter 1234 into an Inspector rotation slot. Then run `transform.rotation=Quaternion.identity;`. It will snap to 1080, which is the closest multiple of 360 to your starting 1234.

That's why the Inspector seems to prefer -180 to 180, since most slots usually start at 0. But if a slot starts at 180, suddenly Unity prefers 0-360 for that one slot.

13. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
Thx @Owen-Reynolds for your Re numbers --> Vector and Rotation link . Good place to start.

Thanks All for the great support!

At the end I finish making the all the math for getting what is in the inspector field. My script is different because the GameObject starting rotation is different from 000 (identity). I think my starting rotation is -90 in Y. Here is the script

Code (CSharp):
1.
2. // drag and drop in the inspector game object to look at
3. public Transform myGameObjectTransform;
4. public float xAngle; // the result value in angles
5.
6. void FixedUpdate()
7.     {
8.         // Get X
9.         if (myGameObjectTransform.eulerAngles.y > 180f)
10.         {
11.             if (dragAlphaArrow.eulerAngles.x > 256f)
12.                 xAngle = (myGameObjectTransform.eulerAngles.x *-1f) +360f;
13.             else
14.                 xAngle= -myGameObjectTransform.eulerAngles.x;
15.         } else {
16.
17.             if (myGameObjectTransform.eulerAngles.x > 256f)
18.                 xAngle= myGameObjectTransform.eulerAngles.x  - 180f;
19.             else
20.                 xAngle= ((myGameObjectTransform.eulerAngles.x * -1f) + 180f) * -1f;
21.         }
22. }
I repeat: My starting rotation is -90 in Y. So that is the reason I put strange arbitrary values as for example 256. And is working correctly. I'm open to critics.

I'm an artist, not a coder or an engineer. If you want to check values for debugging I suggest strongly to make something like this, to double check what you are doing.

Last edited: Mar 12, 2017
maurizio55 likes this.
14. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474  15. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
@Eric5h5 Thanks for your comment. I take my time to understand the problem before answering to you. I disagree with your comment.

Because is not just "Transform.eulerAngles" but the values are not the same. If i go negative go over 270 with no sign. And you get positive numbers with no sign, so you need to compare with another point, etc. Also you need to find that in the documentation and since there are a lot of rotation functions it takes time to understand there is no direct way to get the value.

And as an artist looking the inspector the result bothers me that I can´t just use that value that is in there all the time as I do for example for position , scale or other UI transform variables.

Yes probably using Transform > Rotation (X) (with capital R) is a bad idea and creates confusion. But i wish that value to be accessible. Probably there is a better way to call it. Because is not coherent with other components way of getting values. But with a more appropriate name consistent with the inspector can be more useful for dose as me that do want exactly the same value the is in the inspector without losing too much time.

Code (CSharp):
1. float AOA = myAirplaneTransform.eulerInspectorAngle.x;
or

Code (CSharp):
1. float AOA = myAirplaneTransform.getInspectorRotation.x;
or a more intelligent way. But Eric, I wish it as a further because I need it. Actually, in my game, I use it in approximately 100 different game-objects.

vonSchlank likes this.

### Volunteer ModeratorModerator

Joined:
Jul 19, 2006
Posts:
32,354
The inspector values don't exist in anything other than a temporary form used only for display. What is stored on the transform is Transform.rotation, nothing else. You can use Transform.eulerAngles (same as the inspector) to display the rotation in a more familiar form than quaternions. You may have missed this part: "You can temporarily make rotation values like -90, however toggling play mode will reset them to the actual values that you get from Transform.eulerAngles." You can't have a "eulerInspectorAngle" because it doesn't really exist.

--Eric

17. ### BlackPete

Joined:
Nov 16, 2016
Posts:
970
I don't really understand this insistence that you need to get the inspector's values in code. If a certain rotation is mathematically represented by several solutions, then that's just the nature of math. As far as human readability goes, 0 and 360 are both human readable, but mathematically speaking the end result is the same.

Also let's not forget that the inspector is a dev tool. Whatever values are in there are irrelevant to the end user since they'll never see it. I'm not sure placing this kind of requirement on the inspector makes sense.

Let's say that even if you do get the inspector values in the code. Now what? You still can't reliably output to the inspector from code. The inspector is just representing a quaternion.

Someone also pointed out that if you absolutely positively must have values matching between the inspector and code, then you're going to have to do that yourself using a custom drawer.

18. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
If you need to get inspector's values in code, then you need the code I posted earlier. But even that is not enough. You just get only a quarter of the sphere. I was not able to get the other three-quarters. Is not as simple as it appears or my skills are limited.

At the moment using quaternions is out of my comprehension.

Last edited: Sep 2, 2017
19. ### tinyant

Joined:
Aug 28, 2015
Posts:
118
I think you should use C# reflection to get the transform inspector rotation value.
it's just a Vector3Field for temp vector3 value.
so you should get your selected GameObject and get the TransformInspector instance and to get the Temp field (Vector3) in the TransformInspector.

DDeathlonger and AlanMattano like this.
20. ### tinyant

Joined:
Aug 28, 2015
Posts:
118
Code (CSharp):
1.             Vector3 vect3 = Vector3.zero;
2.             MethodInfo mth = typeof(Transform).GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
3.             PropertyInfo pi = typeof(Transform).GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
4.             object rotationOrder = null;
5.             if (pi != null)
6.             {
7.                 rotationOrder = pi.GetValue(targetTrs, null);
8.             }
9.             if (mth != null)
10.             {
11.                 object retVector3 = mth.Invoke(targetTrs, new object[] { rotationOrder });
12.                 vect3 = (Vector3)retVector3;
13.                 Debug.Log("Get Inspector Euler:" + vect3);
14.             }
Try this.
Unity3d Use internal GetLocalEulerAngles method to get the tmp vector3 value in TransformInspector.

21. ### NathanVanHouten

Joined:
Sep 6, 2012
Posts:
1
For each value in transform.eulerAngles or transform.localEulerAngles if it is a child,

if (value >= 270)
value -= 360;

22. ### Baumkuchen

Joined:
Feb 14, 2016
Posts:
8
Is there no other way to get the EulerAngle? Unity calculate it by its own.... so could anybody write a post how to calculate it like Unity does^^.

AlanMattano likes this.
23. ### Janoschii

Joined:
Oct 15, 2014
Posts:
9
@AlanMattano The script solved this problem for me and RectTransform. You need than to ignore the rotation values of the RectTransform Component in the inspector and only work with the values of the RectTransformRotator component. I can now set any value and also animate to any value. No matter if they are more than 360° or less than 0°. I use the asset Advanced Inspector so I could easily expose properties. You would need to build a own custom inspector to expose the properties or buy Advanced Inspector.

``````
using UnityEngine;

namespace Lib.Jesko.Helper
{
[ExecuteInEditMode]
public class RectTransformRotator : MonoBehaviour
{
void Awake()      { if( rt == null ) rt = GetComponent<RectTransform>(); }
void OnValidate() { if( rt == null ) rt = GetComponent<RectTransform>(); }

[SerializeField, HideInInspector] RectTransform rt;

[SerializeField, HideInInspector] float _lx;
[SerializeField, HideInInspector] float _ly;
[SerializeField, HideInInspector] float _lz;

[Inspect] public float   localX        { get { return _lx; }  set { _lx = value; rt.localEulerAngles = new Vector3(_lx,_ly,_lz); } }
[Inspect] public float   localY        { get { return _ly; }  set { _ly = value; rt.localEulerAngles = new Vector3(_lx,_ly,_lz); } }
[Inspect] public float   localZ        { get { return _lz; }  set { _lz = value; rt.localEulerAngles = new Vector3(_lx,_ly,_lz); } }
[Inspect] public Vector3 localRotation { get { return new Vector3(_lx,_ly,_lz); }  set { _lx = value.x; _ly = value.y; _lz = value.z; rt.localEulerAngles = new Vector3(_lx,_ly,_lz);  } }
}
}

``````

Last edited: Mar 2, 2018
ModLunar and AlanMattano like this.
24. ### tinyant

Joined:
Aug 28, 2015
Posts:
118
In Unity2018 U can just call UnityEditor.TransformUtils.GetInspectorRotation(transform); to get inspector values. 25. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
A note: like the accepted solution just above, TansformUtils is editor only. I feel like people wanting this are wanting to use the values during a real game, for example directly checking eulerAngles.z>45 without having to worry about it having a different value outside of the Inspector.

26. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
SUPER AWESOME!

Agree completely. But can be useful to start understanding how rotation works in Unity C#
Hi, @Adam-Buckner I know that you have done this before but >
I feel now what is missing from Unity is a big nice live tutorial only about the rotation.
• Using Physics force
• Force needed and C# interaction.

• Without using physics using C#
• Difference between Rotate and Rotation
> Rotate: adding rotation angles to the actual rotation? spin
> Rotation: rotate to a final fixed direction angle using the global world space? fix

• How to Set Globally the game object
> to a fix rotation in world space.
> and make spin it in world space adding angles.
• How to Set Locally the game object
> to a fix rotation
> and make it spin it local space.

• How to Get Globally the game object
> the fix rotation in world space
> and get the spin difference.
• How to Get Local
> fix rotation
> and the spin difference.
The pre-recorded live tutorials are also awesome!

Last edited: May 16, 2018
Mikhail94, DDeathlonger and tinyant like this.
27. ### ClayBudin

Joined:
May 10, 2017
Posts:
6
Just to chime in here. I understand that there are multiple Euler Angle representations of
any given Quaternion, but I do think it strange the way Unity does the conversion. If I have
a script which has:

``gameObj.transform.rotation = Quaternion.identity;``

and I run it on an object, that object's Rotation values in the Inspector sometimes show up
as 0,0,0, but sometime they also come up as 0,-360,0 or even -180,-180,-180. I understand
that these are equivalent, but certainly the Identity Quaternion should always translate to
0,0,0 shouldn't it?

Clay Budin
NYC

28. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
The Inspector tries to use values as close as possible to how it started. The idea is, suppose you start Inspector y at -270 and have it naturally spin. In the Inspector, you'll see -269, -268 ... looks very nice. But for real, in the program, y was converted to a "canonical" value of 90. Run the same program with y starting at 450 and in the program it will still convert to 90. But now the Inspector shows it going 451, 452 ... .

I wrote this a different way in some posts back in the thread.

29. ### ClayBudin

Joined:
May 10, 2017
Posts:
6
Interesting. And I guess that makes sense, from one point for view at least.

I'm writing a simple tool to clear transforms and it would be good for the user
if clearing the rotation set it to 0 0 0, rather than something else that might
be equivalent but doesn't immediately look like it.

Has anyone done this before? Is the answer to "ramp down" the rotations
gradually from whatever values they are to 0 0 0 so the Inspector represents
it that way?

Thanks,
Clay Budin
NYC

AlanMattano likes this.
30. ### AAAAAAAAAE

Joined:
Jun 8, 2013
Posts:
84
You are a life saver!

31. ### curtiswer_unity

Joined:
Oct 1, 2018
Posts:
1
So if there is a parent you can just do Vector3.Angle(transform.parent.up, transform.forward) - 90. This will return the value in the inspector for X, and can be easily modified for Y and Z (Using transform.parent.forward and transform.parent.right). If there isn't a parent you can use Vector3.up.
You can't use this to set the value, but with Rotate you should figure it out.
To clarify you can't use tranform.up for the child, as that wouldn't distinguish up from down
Similarly, Vector3.Angle(transform.parent.forward, transform.forward) won't work properly.

An example of me using this to clamp a GameObject named Sphere's x rotation to -12, while trying to aim the object at a target GameObject.
bool Aim()
{
Sphere.transform.rotation = Quaternion.LookRotation(Vector3.RotateTowards(Sphere.transform.forward, target.transform.position-Sphere.transform.position, TurnSpeed*Time.deltaTime, 0.0f));
float angle = Vector3.Angle(transform.up, Sphere.transform.forward);
if (angle > 102)
{
Sphere.transform.localEulerAngles = Sphere.transform.localEulerAngles < 0
? new Vector3(-12, Sphere.transform.localEulerAngles, Sphere.transform.localEulerAngles)
: new Vector3(12, Sphere.transform.localEulerAngles, Sphere.transform.localEulerAngles);
return false;
}
return true;
}

Last edited: Oct 12, 2018
32. ### Cherubim79

Joined:
May 3, 2014
Posts:
56
I've looked at this thread and have done the math, and am still wondering about a way to get the original Inspector View's Euler Angles in the scene at runtime, not to use them in a game actually. I googled for UnwrapAngle and found it on a page, which looks like it only handles the 360 condition. When I bring an X value past 90 degrees it makes the Y and Z 180 degrees, and starts to subtract from X until I bring X to 270 degrees in the Inspector.

As a simple test, I tried putting both the UnityEditor.TransformUtils.GetInspectorRotation vector, which understandably only works in the editor, and the transform.localEulerAngles converted over to a Quaternion, and the Quaternions are different as I see.

I also tried implementing an Euler to Quaternion formula I found on Wikipedia, which had different results in terms of numbers from Unity's implementation, both on the inspector angles and localEulerAngles.

I'm only interested in the math that converts between Euler Angles and Quaternions in Unity so that I can understand them, as well as the method by which Unity changes Euler angles. My interest is mostly in understanding Quaternions for gaming, mathematical, and scientific purposes. I simply want to understand the conversion math involved, which seems to create a lot of confusion if you want to understand it. Seems like a rational and reasonable request, especially since it looks like the transform's local to world matrix is read only.

EDIT: Looks like I found a workaround. I built a Rotation MonoBehavior that stores a Vector3, Quaternion, and Transform, on its Update() function I set Q = Quaternion.Euler(V); T.localRotation = Q; where V is my originating Vector3, and it works as a pass-through component, changing V rather than the object's rotation directly. You obviously wouldn't want to do this ubiquitously throughout Unity, but if you're trying to understand how Quaternions work, it can help you gain some insight. I had a gaming company that I tried to apply for once that asked me during an interview questionnaire and test if I knew Quaternions and Transform Matrices. So I set out to want to understand them. It sounds kind of like an unreasonable question for an interview related to Unity3D programming, considering that Quaternions are hidden behind the scenes in Unity, you would never want to change them directly, neither are you able to change the transform matrices for a Transform. I'd say that God saved me from working for them since they're asking questions they might not even know.

Last edited: Nov 24, 2018
33. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
I really think you need to build something like this visual helper (down here) because is not so simple to understand in local space the result when you make just the math. Unfortunately, I do not have time to look for the code. But is time let me I will try to put here the cs code.

34. ### Cherubim79

Joined:
May 3, 2014
Posts:
56
I built my own actually and figured out some interesting things about Quaternions.

Firstly, order matters at EVERY step in the process. The exercise was to figure out if I could get a 1 to 1 conversion from Euler to Quaternion and back. I'm posting this to help developers who may be scratching their heads over this one.

Firstly, most of the information you see on Euclideanspace and Wikipedia is wrong for Unity, why? Simple, order matters. The ones on those sites assume XYZ order, you have to build your conversion function from Euler to Quaternion in YXZ order to match what the editor says, that means:

q.w = sy*sx*sz+cy*cx*cz
q.x = cy*sx*cz+sy*cx*sz
q.y = sy*cx*cz-cy*sx*sz
q.z = cy*cx*sz-sy*sx*cz

Where sx = Sine(X/2) and cx = Cosine(X/2), cy/sy for Y/2, and cz/sz for Z.

Some code:
``````
double x = ((double)euler.x) / 360.0 * 2.0 * Math.PI;
double y = ((double)euler.y) / 360.0 * 2.0 * Math.PI;
double z = ((double)euler.z) / 360.0 * 2.0 * Math.PI;

// Abbreviations for the various angular functions
double cx = Math.Cos(x * 0.5);
double sx = Math.Sin(x * 0.5);
double cy = Math.Cos(y * 0.5);
double sy = Math.Sin(y * 0.5);
double cz = Math.Cos(z * 0.5);
double sz = Math.Sin(z * 0.5);
Vector4 xSandwich = new Vector4((float)sx, 0f, 0f, (float)cx);
Vector4 ySandwich = new Vector4(0f, (float)sy, 0f, (float)cy);
Vector4 zSandwich = new Vector4(0f, 0f, (float)sz, (float)cz);
Quaternion q5 = CreateVectorSandwich(ySandwich, xSandwich, zSandwich);
``````

``````
public static Vector4 SandwichProduct(Vector4 q1, Vector4 q2)
{
Vector4 q;
q.w = -q1.x * q2.x - q1.y * q2.y - q1.z * q2.z + q1.w * q2.w;
q.x = q1.x * q2.w + q1.y * q2.z - q1.z * q2.y + q1.w * q2.x;
q.y = -q1.x * q2.z + q1.y * q2.w + q1.z * q2.x + q1.w * q2.y;
q.z = q1.x * q2.y - q1.y * q2.x + q1.z * q2.w + q1.w * q2.z;
return q;
}

public static Quaternion CreateVectorSandwich(Vector4 a, Vector4 b, Vector4 c)
{
Vector4 v = SandwichProduct(SandwichProduct(a, b), c);
Quaternion q = new Quaternion(v.x, v.y, v.z, v.w);
return q;
}
``````

Next, despite all of the public information that treats Quaternions like some esoteric transcendental magic when it comes to the matrix of rotation, it's not. Order matters there too, which makes me question a lot of things about Quaternions even more, they're definitely not as great as people try to hype them up to be, but the one thing they do well is apply a combined rotation, which is needed to get around the Gimbal Lock problem, although, I've read some forum posts of people having Gimbal Lock issues with Quaternions, though I haven't seen such a problem manifest. Euclideanspace briefly mentions some issues they had with discrepancies between them and NASA standards.

Anyway, in order to reconstruct the Rotation Matrix properly, you need to swap out how you treat X, Y, and Z in your matrix when you construct it. I built all 36 permutations through code like so:

``````
public double[,] CreateRotationMatrixFromQuaternion(double first, double second, double third, double w)
{
double[,] matrix = new double[3, 3];
double x = first;
double y = second;
double z = third;
double m1_1 = 1.0 - 2.0 * (y * y + z * z);
double m1_2 = 2.0 * (x * y - z * w);
double m1_3 = 2.0 * (x * z + y * w);

double m2_1 = 2.0 * (x * y + z * w);
double m2_2 = 1.0 - 2.0 * (x * x + z * z);
double m2_3 = 2.0 * (y * z - x * w);

double m3_1 = 2.0 * (x * z - y * w);
double m3_2 = 2.0 * (y * z + x * w);
double m3_3 = 1.0 - 2.0 * (x * x + y * y);
matrix[0, 0] = m1_1; matrix[0, 1] = m1_2; matrix[0, 2] = m1_3;
matrix[1, 0] = m2_1; matrix[1, 1] = m2_2; matrix[1, 2] = m3_3;
matrix[2, 0] = m3_1; matrix[2, 1] = m3_2; matrix[2, 2] = m3_3;
return matrix;
}

public double[] CreateEulerFromRotationMatrix(double[,] matrix, int idx1, int idx2, int idx3)
{
double[] angles = new double;
double ftany = matrix[2,1];
double ftanx = matrix[2,2];
double first = System.Math.Atan2(ftany, ftanx);
double stany = matrix[1,0];
double stanx = matrix[0,0];
double second = System.Math.Atan2(stany, stanx);
double tsiny = matrix[2, 0];
double third = System.Math.Asin(-1.0 * tsiny);
angles[idx1] = first;
angles[idx2] = second;
angles[idx3] = third;
return angles;
}

public List<double[]> GetAllEulerAngles(NewQuaternion q)
{
List<double[,]> matrices = new List<double[,]>();
List<double[]> angles = new List<double[]>();
for (int i1=0;i1<6;i1++)
{
}
return angles;
}
``````

Then I could test in the editor by rotating against a copy of an object that I sent the Euler angles to. The one that worked was index 29, which should have a matrix created in ZXY order in CreateRotationMatrixFromQuaternion, and the variables are pulled back in ZYX order, with Z being the one that's pulled first by Arcsine. It's the only permutation which doesn't suffer any weird flipping problems when recreated.

So to recap, create your Euler to Quaternion function in YXZ order, not simply switching around variables but create the function by the sandwich (V_out=q*V_in*q^-1) products of (Y*X)*Z and put your variables in XYZ (q.x = x, q.y = y, q.z = z, q.w = w). Then on pulling them from Quaternion to Euler create your rotation matrix in ZXY order and pull your variables out in reverse ZYX.

By the way, in defense of the Unity fellows, the actual Arcsine, Arccosine, and Arctangent functions themselves are at the root of why an X angle of say 91 degrees Euler will have a Y and Z of 180 if both Y & Z were 0.

I'm looking through this article now and wondering if I can pull back 2 different Euler Angles for every pull, and see if I can simply pick the best one based on some factors for how "pretty" I want to make the output essentially:

I'll update if that goes well.

Really makes me think of Cosine and Sine problems on the whole though and rotation systems in computers. I've been mucking around some hypotheses in my head on how to achieve a better rotational system by retaining original quadrant information of Cosines and Sines, the problem is it doesn't look like it's commutative. Could potentially help with the spectral leakage problem in DSP with Fourier Transforms. I dated a gal once, prettiest gal I ever met, her father worked at NASA for Mission Control when he was alive, so I know he knew all about Quaternions and DSP, he was a radio communications expert, engineer, and chemist. She laughed at me when I mentioned Quaternions, and you know what? She's right. I don't wanna go all Sir William Rowan Hamilton here, but I just feel in my gut like there's a better solution to be had for rotations in general, it's been boiling in my mind, just ported some code over from R to C# in Unity for Fourier smoothing of any arbitrary time-series data like stock market data for example, and I noticed the ends of the spectrum have a singularity problem the more you smooth them, and I've been wondering about a potential solution. Just thinking out loud. Cheers.

Last edited: Dec 4, 2018
35. ### Cherubim79

Joined:
May 3, 2014
Posts:
56
It looks like the inverse angle fixes it where X is between 90 and 270 degrees. You take Pi minus the arcsine calculated angle and use its cosine in the arctangent conversion to get an inverted angle as per this paper:

I also show it on the left in the screenshot.

The trouble though comes down to "which Euler is the best pick." Both angles describe the same rotation, however, one is the original notation and one isn't. You could say, "pick the one of the two with the highest X angle", but there are some weird unknowns when you have say {x = 109, y = 181.7, z = 267.1} in the inspector (you can also see that I built a whole rotation class for this for testing purposes). The returned values the regular Unity way are: {x = 71, y = 1.7, z = 87.1} while the inverse angle is {x = 109, y = -178.3, z = -92.9}, which, if clamped within 0-360, is the same as the inspector on the second one, even though it has negative values in it, which works, but means I can't use negatives in the determination of which angle to choose exactly. Things get the trickiest where X is between 180 and 270 it looks like, because a little over X=180 and you have X values on the inverse close to 360, even though the higher is not the right one, until you get past 270. So, given the clamped values, that gives you essentially 4 rotations to choose from, all doing the same thing but represented differently.

So you might have some conditional logic to say choose the highest X unless both are > 180, then do something else, that something else is what I'm figuring out. It's a brain teaser, a real Tower of Hanoi puzzle from the depths of hell, my hats off to the Unity engineers. Actually, ding, ideas.

I'll update when I have more progress on it, it looks like in many scenarios I can get right back to inspector values, but there are a few outliers that get tricky. It's an improvement nonetheless, and I think I may just about have it licked. ***UPDATE***: I've got the problem licked, about as much as perhaps can be, I just need to clean up the code. Ok, so the fix for the problem is what I call Pitch Isolation. You create a new rotation matrix using only the pitch value, in Unity's case the X actually, which is the one obtained by Arcsine rather than Arctangent. On its own rotation matrix with only the pitch value as the Quaternion, you can get one of the two Euler angles representing the Quaternion and apply some rules to it to basically fish a Quaternion out of a Black Hole.

Last edited: Dec 5, 2018
AlanMattano likes this.
36. ### The-any-Key

Joined:
Jan 19, 2019
Posts:
7
@GuardianArchangelJohn
I combined your solution to get the Unity inspectors Euler angle "type" at index 29. And added a 360 over step detector. Every time: last_euler-(current_euler_index19_value+(360*euler_x_360_pass)) is above or below 180 (when it flip sign) I increase or decrease euler_x_360_pass. This however gives me a limitation that I can not rotate above 180 in one tick/update. But I just want to collect the rotations from animations so this is ok for me. Code in update:
Code (CSharp):
1.
2. // Get current euler list
3. Euler_list = GetAllEulerAngles();
4. // Get Unity Euler
5. double[] value = Euler_list;
6. double EulerX_org = Mathf.Rad2Deg * value;
7. double EulerY_org = Mathf.Rad2Deg * value;
8. double EulerZ_org = Mathf.Rad2Deg * value;
9.
11. EulerX = EulerX_org+(360 * euler_x_360_pass);
12. EulerY = EulerY_org+(360 * euler_y_360_pass);
13. EulerZ = EulerZ_org+(360 * euler_z_360_pass);
14.
15. // Check if x passed 360
16. float x_change = (float)last_euler_x - (float)EulerX;
17. if (Mathf.Abs(x_change) >180)
18. {
19.     // Passed 360
20.     // Check direction we passed
21.     if (x_change>0)
22.     {
24.         euler_x_360_pass += 1;
25.     }
26.     else
27.     {
28.         // Sub 360
29.         euler_x_360_pass -= 1;
30.     }
31.     // Recalc euler
32.     EulerX = EulerX_org + (360 * euler_x_360_pass);
33. }
34.
35. // Check if y passed 360
36. float y_change = (float)last_euler_y - (float)EulerY;
37. if (Mathf.Abs(y_change) > 180)
38. {
39.     // Passed 360
40.     // Check direction we passed
41.     if (y_change > 0)
42.     {
44.         euler_y_360_pass += 1;
45.     }
46.     else
47.     {
48.         // Sub 360
49.         euler_y_360_pass -= 1;
50.     }
51.     // Recalc euler
52.     EulerY = EulerY_org + (360 * euler_y_360_pass);
53. }
54.
55. // Check if z passed 360
56. float z_change = (float)last_euler_z - (float)EulerZ;
57. if (Mathf.Abs(z_change) > 180)
58. {
59.     // Passed 360
60.     // Check direction we passed
61.     if (z_change > 0)
62.     {
64.         euler_z_360_pass += 1;
65.     }
66.     else
67.     {
68.         // Sub 360
69.         euler_z_360_pass -= 1;
70.     }
71.     // Recalc euler
72.     EulerZ = EulerZ_org + (360 * euler_z_360_pass);
73. }
74.
75. // Save last
76. last_euler_x = EulerX;
77. last_euler_y = EulerY;
78. last_euler_z = EulerZ;

vonSchlank, dyupa, TheFlyHawk and 3 others like this.
37. ### DavidSWu

Joined:
Jun 20, 2016
Posts:
183
How does pitch isolation work if you are pointing (i.e. Z axis) straight up or straight down?
This is a common case for us because people drive on walls.

38. ### Aslan0227

Joined:
Mar 22, 2018
Posts:
1
gameobject rotation (45,0,0)
Debug.log(transform.eulerAngles.x);
PRİNT = 45
gameobject rotation (135,0,0)
Debug.log(transform.eulerAngles.x);
PRİNT = 45
why !!!!!!!!!

39. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
Print all 3 values. The first gives (45,0,0). The second is (45,180,180), which is the same as (135,0,0) if you know how to read it. That's why people say not to try to read back angles after setting them.

Bunny83 likes this.
40. ### TheFlyHawk

Joined:
Mar 23, 2016
Posts:
56
I just need this feature. Can I provide complete file code?

Joined:
Apr 3, 2019
Posts:
14
Thank you

42. ### The-any-Key

Joined:
Jan 19, 2019
Posts:
7
Here is a simplified version that allow you to just drag this script as an component to an object and it will show the Euler angles in runtime.

Code (CSharp):
1. using System.Collections;
2. using System.Collections.Generic;
3. using UnityEngine;
4.
5. public class EulerGet : MonoBehaviour
6. {
7.     // ===========================================
8.     // EULER CALC
9.     // ===========================================
10.     public double EulerX = 0;
11.     public double EulerY = 0;
12.     public double EulerZ = 0;
13.     // Hold Euler list
14.     private List<double[]> Euler_list;
15.     // Hold last angle to calc angles over 360
16.     private double last_euler_x;
17.     private double last_euler_y;
18.     private double last_euler_z;
19.     // Hold 360 passes
20.     private double euler_x_360_pass=0;
21.     private double euler_y_360_pass=0;
22.     private double euler_z_360_pass=0;
23.     // ===========================================
24.
25.     // Use this for initialization
26.     void Start ()
27.     {
28.         // Init euler calc
29.         init_euler_calc();
30.     }
31.
32.     // Update is called once per frame
33.     void Update ()
34.     {
35.         // Update euler calc
36.         update_euler_calc();
37.     }
38.
39.     // ===========================================
40.     // EULER CALC
41.     // ===========================================
42.     public void init_euler_calc()
43.     {
44.         // Init first Euler as reference
45.         float x = transform.eulerAngles.x / 360.0f * 2.0f * Mathf.PI;
46.         float y = transform.eulerAngles.y / 360.0f * 2.0f * Mathf.PI;
47.         float z = transform.eulerAngles.z / 360.0f * 2.0f * Mathf.PI;
48.
49.         // Abbreviations for the various angular functions
50.         double cx = Mathf.Cos(x * 0.5f);
51.         double sx = Mathf.Sin(x * 0.5f);
52.         double cy = Mathf.Cos(y * 0.5f);
53.         double sy = Mathf.Sin(y * 0.5f);
54.         double cz = Mathf.Cos(z * 0.5f);
55.         double sz = Mathf.Sin(z * 0.5f);
56.
57.         Vector4 xSandwich = new Vector4((float)sx, 0f, 0f, (float)cx);
58.         Vector4 ySandwich = new Vector4(0f, (float)sy, 0f, (float)cy);
59.         Vector4 zSandwich = new Vector4(0f, 0f, (float)sz, (float)cz);
60.         Quaternion q5 = CreateVectorSandwich(ySandwich, xSandwich, zSandwich);
61.
62.         /*
63.         // Get current euler list
64.         Euler_list = GetAllEulerAngles();
65.         // Show list
66.         foreach (double[] test_value in Euler_list)
67.         {
68.             Debug.Log("x:" + Mathf.Rad2Deg*test_value + " y:" + Mathf.Rad2Deg * test_value + " z:" + Mathf.Rad2Deg * test_value);
69.         }
70.         */
71.     }
72.
73.     public void update_euler_calc()
74.     {
75.         // Get only Unity euler
76.         double[] value = GetUnityEulerAngles();
77.
78.         double EulerX_org = Mathf.Rad2Deg * value;
79.         double EulerY_org = Mathf.Rad2Deg * value;
80.         double EulerZ_org = Mathf.Rad2Deg * value;
81.
83.         EulerX = EulerX_org + (360 * euler_x_360_pass);
84.         EulerY = EulerY_org + (360 * euler_y_360_pass);
85.         EulerZ = EulerZ_org + (360 * euler_z_360_pass);
86.
87.         // Check if x passed 360
88.         float x_change = (float)last_euler_x - (float)EulerX;
89.         if (Mathf.Abs(x_change) > 180)
90.         {
91.             // Passed 360
92.             // Check direction we passed
93.             if (x_change > 0)
94.             {
96.                 euler_x_360_pass += 1;
97.             }
98.             else
99.             {
100.                 // Sub 360
101.                 euler_x_360_pass -= 1;
102.             }
103.             // Recalc euler
104.             EulerX = EulerX_org + (360 * euler_x_360_pass);
105.         }
106.
107.         // Check if y passed 360
108.         float y_change = (float)last_euler_y - (float)EulerY;
109.         if (Mathf.Abs(y_change) > 180)
110.         {
111.             // Passed 360
112.             // Check direction we passed
113.             if (y_change > 0)
114.             {
116.                 euler_y_360_pass += 1;
117.             }
118.             else
119.             {
120.                 // Sub 360
121.                 euler_y_360_pass -= 1;
122.             }
123.             // Recalc euler
124.             EulerY = EulerY_org + (360 * euler_y_360_pass);
125.         }
126.
127.         // Check if z passed 360
128.         float z_change = (float)last_euler_z - (float)EulerZ;
129.         if (Mathf.Abs(z_change) > 180)
130.         {
131.             // Passed 360
132.             // Check direction we passed
133.             if (z_change > 0)
134.             {
136.                 euler_z_360_pass += 1;
137.             }
138.             else
139.             {
140.                 // Sub 360
141.                 euler_z_360_pass -= 1;
142.             }
143.             // Recalc euler
144.             EulerZ = EulerZ_org + (360 * euler_z_360_pass);
145.         }
146.
147.         // Save last
148.         last_euler_x = EulerX;
149.         last_euler_y = EulerY;
150.         last_euler_z = EulerZ;
151.     }
152.
153.     public static Vector4 SandwichProduct(Vector4 q1, Vector4 q2)
154.     {
155.         Vector4 q;
156.         q.w = -q1.x * q2.x - q1.y * q2.y - q1.z * q2.z + q1.w * q2.w;
157.         q.x = q1.x * q2.w + q1.y * q2.z - q1.z * q2.y + q1.w * q2.x;
158.         q.y = -q1.x * q2.z + q1.y * q2.w + q1.z * q2.x + q1.w * q2.y;
159.         q.z = q1.x * q2.y - q1.y * q2.x + q1.z * q2.w + q1.w * q2.z;
160.
161.         return q;
162.     }
163.
164.     public static Quaternion CreateVectorSandwich(Vector4 a, Vector4 b, Vector4 c)
165.     {
166.         Vector4 v = SandwichProduct(SandwichProduct(a, b), c);
167.         Quaternion q = new Quaternion(v.x, v.y, v.z, v.w);
168.         return q;
169.     }
170.
171.     public double[,] CreateRotationMatrixFromQuaternion(double first, double second, double third, double w)
172.     {
173.         double[,] matrix = new double[3, 3];
174.         double x = first;
175.         double y = second;
176.         double z = third;
177.
178.         double m1_1 = 1.0 - 2.0 * (y * y + z * z);
179.         double m1_2 = 2.0 * (x * y - z * w);
180.         double m1_3 = 2.0 * (x * z + y * w);
181.
182.         double m2_1 = 2.0 * (x * y + z * w);
183.         double m2_2 = 1.0 - 2.0 * (x * x + z * z);
184.         double m2_3 = 2.0 * (y * z - x * w);
185.
186.         double m3_1 = 2.0 * (x * z - y * w);
187.         double m3_2 = 2.0 * (y * z + x * w);
188.         double m3_3 = 1.0 - 2.0 * (x * x + y * y);
189.
190.         matrix[0, 0] = m1_1; matrix[0, 1] = m1_2; matrix[0, 2] = m1_3;
191.         matrix[1, 0] = m2_1; matrix[1, 1] = m2_2; matrix[1, 2] = m3_3;
192.         matrix[2, 0] = m3_1; matrix[2, 1] = m3_2; matrix[2, 2] = m3_3;
193.
194.         return matrix;
195.     }
196.
197.     public double[] CreateEulerFromRotationMatrix(double[,] matrix, int idx1, int idx2, int idx3)
198.     {
199.         double[] angles = new double;
200.         double ftany = matrix[2, 1];
201.         double ftanx = matrix[2, 2];
202.         double first = System.Math.Atan2(ftany, ftanx);
203.         double stany = matrix[1, 0];
204.         double stanx = matrix[0, 0];
205.         double second = System.Math.Atan2(stany, stanx);
206.         double tsiny = matrix[2, 0];
207.         double third = System.Math.Asin(-1.0 * tsiny);
208.
209.         angles[idx1] = first;
210.         angles[idx2] = second;
211.         angles[idx3] = third;
212.
213.         return angles;
214.     }
215.
216.     public double[] GetUnityEulerAngles()
217.     {
218.         // Get local transform
219.         Quaternion q;
220.         q.x = transform.localRotation.x;
221.         q.y = transform.localRotation.y;
222.         q.z = transform.localRotation.z;
223.         q.w = transform.localRotation.w;
224.         // Hold return values
225.         double[,] matrices;
226.         double[] angles;
227.         // Get needed matrix
228.         matrices=CreateRotationMatrixFromQuaternion(q.z, q.x, q.y, q.w);
229.         // Calc Unity Euler
230.         angles=CreateEulerFromRotationMatrix(matrices, 2, 1, 0);
231.         // Return Unity euler
232.         return angles;
233.     }
234.
235.     public List<double[]> GetAllEulerAngles()
236.     {
237.         // Get local transform
238.         Quaternion q;
239.         q.x = transform.localRotation.x;
240.         q.y = transform.localRotation.y;
241.         q.z = transform.localRotation.z;
242.         q.w = transform.localRotation.w;
243.
244.         List<double[,]> matrices = new List<double[,]>();
245.         List<double[]> angles = new List<double[]>();
246.
253.
254.         for (int i1 = 0; i1 < 6; i1++)
255.         {
262.         }
263.
264.         return angles;
265.
266.     }
267. }
268.

### Guest

Hello!

This is a simple script showing how you can get inspector like values of any transform.

Vector3 angle = transform.eulerAngles;
float x = angle.x;
float y = angle.y;
float z = angle.z;

if (Vector3.Dot(transform.up, Vector3.up) >= 0f)
{
if (angle.x >= 0f && angle.x <= 90f)
{
x = angle.x;
}
if (angle.x >= 270f && angle.x <= 360f)
{
x = angle.x - 360f;
}
}
if (Vector3.Dot(transform.up, Vector3.up) < 0f)
{
if (angle.x >= 0f && angle.x <= 90f)
{
x = 180 - angle.x;
}
if (angle.x >= 270f && angle.x <= 360f)
{
x = 180 - angle.x;
}
}

if (angle.y > 180)
{
y = angle.y - 360f;
}

if (angle.z > 180)
{
z = angle.z - 360f;
}

Debug.Log(angle + " :::: " + Mathf.Round(x) + " , " + Mathf.Round(y) + " , " + Mathf.Round(z));

MogilColcol, Snake-M3, Dibloo and 5 others like this.
44. ### AlanMattano

Joined:
Aug 22, 2013
Posts:
1,474
Thx @ForgeArts for the script I put it in clean.

Works but with limitation of X -90° +90° only

Code (CSharp):
1. using UnityEngine;
2.
3. // Print transform rotation only up to 90° of this object
5. public class InspectRotation_Simple : MonoBehaviour
6. {
7.     void Update()
8.     {
9.         if (Input.GetKeyDown(KeyCode.Space))
10.         {
11.             Vector3 angle = transform.eulerAngles;
12.             float x = angle.x;
13.             float y = angle.y;
14.             float z = angle.z;
15.
16.             if (Vector3.Dot(transform.up, Vector3.up) >= 0f)
17.             {
18.                 if (angle.x >= 0f && angle.x <= 90f)
19.                 {
20.                     x = angle.x;
21.                 }
22.                 if (angle.x >= 270f && angle.x <= 360f)
23.                 {
24.                     x = angle.x - 360f;
25.                 }
26.             }
27.             if (Vector3.Dot(transform.up, Vector3.up) < 0f)
28.             {
29.                 if (angle.x >= 0f && angle.x <= 90f)
30.                 {
31.                     x = 180 - angle.x;
32.                 }
33.                 if (angle.x >= 270f && angle.x <= 360f)
34.                 {
35.                     x = 180 - angle.x;
36.                 }
37.             }
38.
39.             if (angle.y > 180)
40.             {
41.                 y = angle.y - 360f;
42.             }
43.
44.             if (angle.z > 180)
45.             {
46.                 z = angle.z - 360f;
47.             }
48.
49.             Debug.Log(angle + " :::: " + Mathf.Round(x) + " , " + Mathf.Round(y) + " , " + Mathf.Round(z));
50.         }
51.     }
52. }

Last edited: May 23, 2019
mbaske and Deleted User like this.
45. ### Shippety

Joined:
May 9, 2014
Posts:
31
This is just what I needed to know, thanks!

46. ### SIRIUSTECHSOLUTIONS

Joined:
Apr 14, 2016
Posts:
9
Hello, just try this one float angle = System.Math.Round((double)transform.eulerAngles.y, 1);

47. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
Not an answer. Read the rest of the Q: when the angle is 0, the Inspector might show 0, or 360, 720, -360, or it might even show 180 or -180. They want to know which one, from inside of the program.

DonLoquacious likes this.

Joined:
Jul 23, 2018
Posts:
1,740
49. ### Owen-Reynolds

Joined:
Feb 15, 2012
Posts:
1,821
prosto666, vonSchlank and AlanMattano like this.
50. ### SpaceManDan

Joined:
Aug 3, 2013
Posts:
15

So simple. Thousands of words from so many people... Yet, this is all anybody really needed. Thanks!