confusion about transform.rotate()

I have four rectangular platforms put around a square platform. On the end of each rectangular platforms, I set up some spawn points to generate cubes with arrows sign on its face. The generated cube will be rotated immediately to change the direction that the arrow indicated after it is generated. All other three rectangular platforms were rotated from the ‘0’ platform. But my original codes that rotating the cube do not work for platform 1 & 3. Although I have found how to change it to make it works, I still cannot understand why my original codes failed. The version I used is 2019.4.18f1

Unworkable way

GameObject cube = Instantiate(dirCubeTypes[Random.Range(0, 6)], dirCubePoints[Random.Range(0, 4)]);
cube.transform.Rotate(transform.forward, 90 * Random.Range(0, 4));

The figure below shows the cube generated on the platfrom 3. I want it to rotate around z-axis, but the codes above make it rotate around its x-axis instead of z-aixs. I know the third parameter is relativeTo**,** and the default value is Space.self. Why doesn’t the codes above make it rotate along the z-axis in its own local coordinate system?

7004054--828026--upload_2021-4-4_7-8-10.png

Workable ways

I have tried out three workable ways, but for two of them, I still don’t know why it works.

This one works well. If I use Vector3.forward in Space.self, I think it should rotate around the x-axis of the cube itself, but it rotate around its z-axis.

GameObject cube = Instantiate(dirCubeTypes[Random.Range(0, 6)], dirCubePoints[Random.Range(0, 4)]);
cube.transform.Rotate(Vector3.forward, 90 * Random.Range(0, 4));

This one also works well. But I am confused either.

GameObject cube = Instantiate(dirCubeTypes[Random.Range(0, 6)], dirCubePoints[Random.Range(0, 4)]);
cube.transform.Rotate(transform.forward, 90 * Random.Range(0, 4), Space.World
);

The last one is the only one that works as I think.

GameObject cube = Instantiate(dirCubeTypes[Random.Range(0, 6)], dirCubePoints[Random.Range(0, 4)]);
cube.transform.RotateAround(transform.position, transform.forward, 90*Random.Range(0,4));

You’re feeding it transform.forward for the axis, and transform.forward is in world space. So because the default space is in its own local space, you’re using a world space vector in local space, and that mismatch is going to lead to nonsensical results. You can use Vector3.forward and local space, or transform.forward and world space.

1 Like

Thanks for your reply! So although transform.forward represents the z-axis for a game object, it should be used in world space? I had previously misunderstood that since transform.forward could change with the rotation of the object, it was used in local space.

It’s the opposite - what “forward” is to me is always “in front of my face”, like how my glasses never move in my field of vision, that’s my local space. But to an outside observer - world space - my glasses are moving all the time.

1 Like

This is clear for me now with your explanation, many thanks!

I think I’ve learned over time that relating rotations to someone’s head is the only way rotations reliably make sense to people. Like “rotating on the X axis is nodding your head”, etc.