- Home /
[OAFAT]Why does transform.rotation.x = 45 not work
This is a reference answer for questions that have code that attempt to directly manipulate a rotation's x, y, or z component.
Answer by robertbu · Sep 29, 2014 at 03:38 PM
Summary:
The x, y, and z components of transform.rotation are not angles and cannot be manipulated as angles.
You can use transfrom.eulerAngles, but there are some serious issues you need to understand to avoid problems.
Transform.Rotate() is often a simpler and better solution for rotating than trying to change the angles directly.
Quaternions are not angles
Transform.rotations is a Quaternion...a non-intuitive, 4D construct based on complex numbers. The individual x, y, z, and w components are not angles and have values between -1.0 an 1.0. Unless you have a firm understanding of Quaternion math, I recommend against directly accessing x,y,z, and w. From the reference:
[Quaternions] are based on complex numbers and are not easy to understand intuitively. You almost never access or modify individual Quaternion components (x,y,z,w).
In fact, of the hundreds of rotation questions I've answered, and the thousands I've read, I've never seen a question that required directly accessing x,y,z or w to solve. Here are some references to understand more about Quaternions in general and the use of Quaternions in Unity3D:
1) UnityGem's excellent tutorial: http://unitygems.com/quaternions-rotations-part-1-c/
2) Wikipedia article: http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation
3) Official Unity Video on Quaternions: https://www.youtube.com/watch?v=TdjoQB43EsQ
4) Understanding Quaternions: http://3dgep.com/understanding-quaternions/
Quaternions are not required for many rotations
Many rotations (and likely the one you were attempting) can be accomplished through other (simpler) methods, including 'Transform.Roate()' and directly accessing 'Transform.eulerAngles':
Transform.Rotate() - Rotate() does a relative rotation, and by default, a local rotation. For example:
transform.Rotate(0,45,0);
...will rotate and additional 45 degrees from the current rotation on the object's 'y' axis. There is an optional second parameter, so:
transform.Rotate(0,45,0,Space.World);
...rotates the object 45 degrees on the world 'y' axis. Here is a bit of sample code. Use the arrow keys to rotate. Use the shift key to change from local to world rotation:
#pragma strict
var speed = 90.0; // Degrees per second;
function Update() {
var x = Input.GetAxis("Vertical") * speed * Time.deltaTime;
var y = -Input.GetAxis("Horizontal") * speed * Time.deltaTime;
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) {
transform.Rotate(x,y,0,Space.World); // World rotation;
}
else {
transform.Rotate(x,y,0); // Local rotation
}
}
EulerAngles - Within limits you can access angles like you are probably trying to do with 'transform.rotation'. These three all do the same thing:
transform.eulerAngles = someVector3;
transform.rotation.eulerAngles = someVector3;
transform.rotation = Quaternion.Euler(someVector3);
Before you get too excited, you need to understand the limits of eulerAngles:
1) They suffer from gimble lock. It is rare for beginners to get in a situation where gimble lock is a problem, but it does happen. Some references on gimble lock:
Excellent YouTube video: https://www.youtube.com/watch?v=zc8b2Jo7mno
Wikipedia article: http://en.wikipedia.org/wiki/Gimbal_lock
2) EulerAngles are derived from the Quaternion and do not maintain a static representation. For example, execute this code:
transform.eulerAngles = (180,0,0);
Debug.Log(transform.eulerAngles);
The output will be (0,180,180)...the same physical rotation represented differently. This changing representation makes eulerAngles difficult for may things, like clamping a rotation or following a rotation. In addition it leads to the next problem:
3) EulerAngles must be assigned all at once. You cannot assign x,y and z independently. This is only a problem for Javascript/Unityscript since the C# compiler will not allow you to assign them independently.
4) For many rotation situations, when using eulerAngles you have to deal with the 360/0 boundary.
---
One way to work around the changing representation problem is to treat EulerAngles as write-only...to never read back the representation. Here is an example:
#pragma strict
public var speed : float = 90.0; // Degrees per second;
public var euler : Vector3 = Vector3.zero;
public var xLimit = 80.0;
public var yLimit = 80.0;
function Start() {
transform.eulerAngles = euler;
}
function Update() {
euler.x += Input.GetAxis("Vertical") * speed * Time.deltaTime;
euler.y -= Input.GetAxis("Horizontal") * speed * Time.deltaTime;
euler.x = Mathf.Clamp(euler.x, -xLimit, xLimit);
euler.y = Mathf.Clamp(euler.y, -yLimit, yLimit);
transform.eulerAngles = euler;
}
This code does a world rotation of a object with a clamp on the angles of rotation. All changes are made to the 'euler' variable, and then the variable is assigned. Since I never read from 'transform.eulerAngles', I don't have to worry about changing representation. Since I control the representation, I can do anything to it I want.
Answer by hammad-zahid · Sep 16, 2016 at 09:36 AM
This will simply work for you:
gameObject.transform.Rotate(new Vector3(0, 0, -1));
Answer by lll4louis · Apr 14, 2019 at 03:17 PM
void Update()
{
if (Input.GetMouseButton(0))
{
transform.eulerAngles += new Vector3(speed, 0, 0);
}
if (Input.GetMouseButton(1))
{
transform.eulerAngles -= new Vector3(speed, 0, 0);
}
I try this on void update, and I find out that if you click the left mouse, it rotate and stop at the top that @robertbu mentioned. But then you stop the left mouse and immediately click the right mouse, it rotate to the bottom and stop again. What happend? see this in youtube: https://youtu.be/f8xwO5vdn7M
Your answer
Follow this Question
Related Questions
Smooth rotation in 90° increments 0 Answers
How to check for NaN 4 Answers
c# modify only one axis of a quaternion 2 Answers
trouble with Quaternion rotation in 360 axis degree 0 Answers
Apply game object rotation using relative VR controller rotation? 2 Answers