It's IMPOSIBLE to set a value to the roatation. (without writing 40+ lines of code!)

Hello.

let’s say the rotation of the of my object is 0,0,0. cool, now I want to ony SET the first value. let’s say to make it 100 (so the rotation would be 100,0,0)
After googling it, I found that dozens of people or more asked it before and none of them got a real answer. I am not looking of an explanation about quaternions and eular angles. there is these values in degrees in the inspector, and I want to just change one value, the x.

some of you may thing that this shoud work:
transform.eulerAngles = new Vector3(100, transform.eulerAngles.y, transform.eulerAngles.z);

             transform.eulerAngles = new Vector3(100, transform.eulerAngles.y, transform.eulerAngles.z);

but it will not work. it does super complicated things. I just want to know 3 things.

1. is it possible to change the first value in simple way or do I need to write 40-60 lines of code to solve it?
2. how
3. if it’s so complicated and can’t be solved in less than dozens of lines of code, why doesn’t unity have a simple way to solve it?

just a proof for you that the way I showed does not work
here is a script:

    void Update()
    {
        if (Input.GetKeyDown("space"))
        {
             transform.eulerAngles = new Vector3(100, transform.eulerAngles.y, transform.eulerAngles.z);
            print(transform.eulerAngles)
        }
    }

and what it does:

It’s possible, it’s as simple as that one liner that you posted.

Not sure what you were expecting though and why you say it’s not working as expected.

Try my code yourself, as you can see in the video, it does not change the values to 100,0,0, but jumps from 100,0,0 to 80,0,0 back to 100,0,0.
It’s either a common misconception or a bug in unity engine itself, I’ll go with a misconception

transform.rotation.eulerAngles, transform.localRotation.eulerAngles.

It’s not a good idea to read from .eulerAngles, even though you can. Those angles are a false construct synthesized for niceties of display to humans. Quaternions have internal x,y,z,w components that are useless to humans but critical to the way they work.

If you want to SET a rotation, use Quaternion.Euler() to produce it, then assign it to either transform.rotation or transform.localRotation

transform.rotation = Quaternion.Euler( 100, 0, 0);

If you need complex multi-axis use (such as a gun turret that can both elevate and traverse), use two transforms parented to each other, and only control one axis per transform.

3 Likes

Well, if you want to get technical, you can’t set it, because it’s not a variable. Euler angles are not explicitly stored. Behind the scenes, Unity uses the Quaternion for everything, and when you ask for Euler angles it converts on the fly. So when you write
transform.eulerAngles = <something>
what Unity actually does is effectively
transform.rotation = Quaternion.Euler(<something>)

and then when you ask what the eulerAngles currently are, Unity effectively does
return transform.rotation.eulerAngles

Since there’s more than one possible set of Euler angles for representing a given Quaternion, you are not guaranteed to get back the same ones that you started with. You might get a different set of angles that represents the same combined rotation.

And since Euler angles are not linearly independent, changing one component (like X) is sometimes equivalent to changing other components. For example, the Euler angles (180, 0, 0) are equivalent to (0, 180, 180). So if you set a Transform’s eulerAngles equal to one of those, and then asked Unity what the eulerAngles currently are, it could return the other one and it wouldn’t be “wrong”.

Setting just the X of the Euler angles is a really weird thing to do, because it doesn’t have any clear geometric meaning. If you set all the angles to something like (100, 0, 0), then that has a clear geometric meaning: It refers to a specific orientation in 3D space, and while Unity might not preserve those exact numbers, it will preserve that orientation. If you ask what the Euler angles are afterward, they might not be (100, 0, 0), but they’ll be equivalent to that.

But setting just the X doesn’t guarantee any particular result. Remember how (180, 0, 0) is equivalent to (0, 180, 180)? Well, once you override the X angle with 100, you could get either (100, 0, 0) or (100, 180, 180), which are not equivalent. Changing just one angle means you don’t know what you’re going to get.

So I replicated your test, but with more logging:

    void Update()
    {
        if (Input.GetKeyDown("space"))
        {
            Vector3 angles = transform.eulerAngles;
            Debug.Log("Before, angles = " + angles);
            angles.x = 100;
            Debug.Log("Modified, angles = " + angles);
            transform.eulerAngles = angles;
            Debug.Log("After, eulerAngles = " + transform.eulerAngles);
        }
    }

Before, angles = (0.0, 0.0, 0.0)
Modified, angles = (100.0, 0.0, 0.0)
After, eulerAngles = (80.0, 180.0, 180.0)

Before, angles = (80.0, 180.0, 180.0)
Modified, angles = (100.0, 180.0, 180.0)
After, eulerAngles = (80.0, 0.0, 0.0)

Before, angles = (80.0, 0.0, 0.0)
Modified, angles = (100.0, 0.0, 0.0)
After, eulerAngles = (80.0, 180.0, 180.0)

Unity is giving you back equivalent orientations, but not the exact numbers that you set. (I suspect it’s trying to follow a rule that pitch shouldn’t be greater than 90 degrees, because that’s how first-person games traditionally work.)

The rotation values displayed in the inspector for this object are doing something weird that doesn’t necessarily match the exact numbers that you set or the exact numbers that Unity gives back, and I’m not totally sure why. Could be there’s a different set of conversion rules for the inspector for some reason.

When you modify Euler angles through the inspector, Unity remembers the exact Euler angles so that they don’t appear to change. But this doesn’t apply when you modify them through code at runtime.

If you want to make a user input system where the user controls something through its Euler angles, then usually you work around this by explicitly storing the current Euler angles yourself, instead of asking Unity what they are. When you get an input to change them, you change your variables, and then modify the Transform to match your variables, and you never change your variables to match the Transform.

(Obviously, this only works if ALL rotations go through your code. If you also want the object to rotate in response to physics or something, you have a much harder problem.)

5 Likes

EXACTLY this… use a float to track the angle, change it via user input, clamp it if you want, then use Quaternion.Euler() to set the axis you want to spin.

It’s kind of funny that the OP didn’t include the console output from his code in his video, because that’s exactly what it shows. If he looked at it, that might have given him some help in understanding how the angles are sometimes surprisingly different from what you assigned them when you read them back. Interestingly, the code he posted has a compile-time bug in it (no semi-colon at the end of Line 6), so maybe he’s never actually seen the output.

In any case, you guys are explaining it to him quite well. There is no bug and there in no misconception. What we have here, I think, is a typical misunderstanding on the part of someone who is new to 3D manipulations. I am teaching a class now in game programming to 85 university students. When I run the demo code I use to show how the Euler angles can come out so different from what you put in, you ought to see the faces they make when I use my toy spaceship to prove that the different angles result in the same orientation. (Picture your Zoom screen filled with thumbnails of people making little “O” shapes with their lips.)

I hope the OP is reading your replies. His consternation will be easy to cope with, if he does.

To be fair, it is rather misleading that the inspector shows a different set of Euler angles than what transform.eulerAngles returns in code.

5 Likes

Hey, gamedev ain’t pretty, you know?

Back in my day we didn’t even HAVE quaternions! We had to go out to the garden, get rocks and hand-paint 0 and 1 on them and bang them together until we had a functioning game we could play! Kids these days…

1 Like

Things were different then.

Ah yes, nice screenshot of Diablo Zero you got there!

I think the main platform I played Rogue on was actually my PalmVx handheld, on a little 160x160 pixel screen.

Ah, the memories. Main platform I played Rogue on was one of these:

You got me there… I don’t think I ever used used paper output for gaming… perhaps on a small plotter calculator, but not a full TTY. Nice!

That was my first real computing experience, using the Teletype model ASR-33. Printed its output in a somewhat hokey angular all-caps font with serifs at the amazing speed of ten characters per second. Was an insane contraption of levers, gears, pullies, and electric motors. When it was typing something, it sounded like there was a gangster inside who was trying to shoot his way out with a Tommy gun. I taught myself how to program on one of those, in an early version of BASIC running on a remote HP-2000 somewhere in Fairfax county, Virginia (never knew where, as we communicated with it via a 300-baud modem).

The year was 1972 and we thought that thing was just so cool. Still do, in a way.

1 Like

It’s kinda weird that “dozens of people” including yourself couldn’t figure it out, it is explained in the Unity documentation itself, which was the first search result when I tried googling it.

For example here: https://docs.unity3d.com/ScriptReference/Transform-eulerAngles.html

Nah, that’s not weird. Happens all the time that some people don’t find things that others do find, even in lopsided numbers. By the law of large numbers, it would be much more weird if no one ever failed to find what others find right away. It just happens.

Fortunately for Unity newcomers, this forum is not StackOverflow, and we don’t castigate people who make the effort to find an answer before asking for it here, even if a lot of us already know what that answer is.