- Home /
Rotate on All Axes Simultaneously
I want to rotate a game object on all three axes simultaneously. More specifically:
I want to start an object with a rotation of 0, 0, 0. Overtime, I want it to rotate evenly on its x axis, its y axis, and its z axis. Specifically, my game object should take about 3-5 seconds to rotate 90 degrees on each axis. The game object's rotation should 30, 30, 30 after 1 second. 60, 60, 60 after 2 seconds. Then 90, 90, 90 after 3 seconds.
I can rotate an object on a single axis easily. But when I try to rotate an object on the y and z axis, the x axis is affected. This makes the object rotate much more slowly on the x axis when I try to rotate on all three axes evenly. This can be scene by adding the following FixedUpdate() method to any game object:
void FixedUpdate()
{
transform.Rotate(Time.deltaTime, Time.deltaTime, Time.deltaTime);
}
How can I rotate an object evenly on all three axes simultaneously?
I asked this question, but apparently it was not a clear question. I hope this question is clear and specific as to exactly what I am trying to do.
Answer by robertbu · Oct 04, 2014 at 07:35 PM
With rotations, what people say they want, and what they really want are often two different things, and getting what they really want is often a frustrating journey in 2) getting a clear definition, and 2) figure out how to write the code. For example, take the script below and attach it to a cube. Over time, it rotates a cube around world axes so that the result is a rotation of (90,90,90). Unity Applies eulerAngles rotations in a ZXY order. So a rotation of (90,90,90) is the same as a rotation of (90,0,0).
using UnityEngine;
using System.Collections;
public class Bug10 : MonoBehaviour {
public float f = 0.0f;
public float speed = 45.0f;
public Vector3 v = Vector3.zero;
void FixedUpdate()
{
if (f < 90.0f) {
v += new Vector3(1,1,1) * Time.deltaTime * speed;
transform.transform.eulerAngles = v;
f += Time.deltaTime * speed;
}
}
}
I've left 'v' public, so you will see that 'v' is 90,90,90, but the rotation reported by Unity (and derived from the Quaternion) will be 90,0,0.
As you can see the rotation looks very strange. If you pickup a cube, put a letter on it so you can see the orientation. Start with the letter facing you. Then while holding it your hands, rotate it for 90 on the world 'z', then 90 on the world 'x' and finally 90 on the world 'y', you will see the letter will be on top, and the rotation will be same as if you just rotated the cube 90 degrees on the 'x'.
Here is another body of code that should you the problem in a different way. The code above does a world rotation around each axis. The following code calculates the end rotation of a local 90,90,90 rotation. It ends up with the same rotation as above. But it takes the most direct route between the two rotations. As you can see, it also is not what I believe you are looking for:
using UnityEngine;
using System.Collections;
public class Bug10 : $$anonymous$$onoBehaviour {
bool rotating = false;
void Update() {
if (!rotating && Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.Space)) {
StartCoroutine(DoTheRotate(90.0f, 90.0f, 90.0f, 3.0f));
}
}
// Input values need to be less than 180.0f
IEnumerator DoTheRotate(float x, float y, float z, float time)
{
rotating = true;
Quaternion qStart = transform.rotation;
transform.Rotate(x, y, z);
Quaternion qEnd = transform.rotation;
transform.rotation = qStart;
float t = 0.0f;
while (t <= 1.0f) {
transform.rotation = Quaternion.Slerp(qStart, qEnd, t);
t += Time.deltaTime / time;
yield return null;
}
transform.rotation = qEnd;
rotating = false;
}
}