Can someone please explain the difference between Transform.Rotate, directly setting Rigidbody.Rotation, and directly setting Transform.eulerAngles? I’m making a small prototype for a spaceship controller and I want the ship to rotate around on its Y axis based to turn left and right and rotate around its X axis to look up and down, and I’ve tried all three of these methods and none of them produce the desired outcome and I cant figure out which one I should use. Using transform.eulerAngles = new Vector3(transform.eulerAngles.x + turnDirection.y*TurnStrength, transform.eulerAngles.y + turnDirection.x*TurnStrength, 0) works almost perfectly, but when the player is facing directly up or down it spazzes out and cant rotate any further on the X. Setting rb.rotation acts pretty much identically. Transform.Rotate lets me rotate 360 degrees on the X axis, which is good, but the rotation acts very strangely, and despite me only rotating around the X and Y axes, the Z rotation of the object always ends up different as well. Is it rotating in world space or something, even though I am using transform.up and transform.right? If anyone knows how to fix the strange rotation with Transform.rotate or how to stop Rigidbody.Rotation from tweaking out it would be much appreciated.
Use Rigidbody if you need physics and Transform if you don’t care about physics.
Getting the current eulerAngles and adding values to them can cause unexpected results, depending on your use case and which values you use. It’s easier to “remember” the eulerAngels yourself in a own variable and then modify this variable and only set the values to the eulerAngels property instead of reading from them, as shown in the manual example code here
By default transform.Rotate rotates in local space but can be made to rotate in world space. I suspect you’re wanting to rotate around the local x axis and rotate around the world y axis, similar to an FPS game. You can do the rotations separately like so:
transform.Rotate(0, Input.GetAxis("Horizontal"), 0, Space.World);
transform.Rotate(Input.GetAxis("Vertical"), 0, 0); // local space
But personally I would use a rigidbody and rotate with AddTorque and AddRelativeTorque.
You can also skip the euler training wheels and go straight to quaternions. The main things you need to know in this context are:
Quaternion.AngleAxiscan be used to generate a rotation around and axis- You combine quaternions with the
Quaternion * Quaternionoperator (order matters, the value you want to ‘add’ second) - You can rotate a direction with the
Quaternion * Vector3operator
If you want to use physics, then you will read all values from the rigidbody, and apply all movement through it. Since Rigidbody doesn’t have .forward etc properties, you can just do the same thing with Vector3.forward * rigidbody.rotation.
So rotation on the forward axis might look like this:
Vector3 forwards = rigidbody.rotation * Vector3.forward;
Quaternion axisRotation = Quaternion.AngleAxis(angle, forwards);
Quaternion finalRotation = rigidbody.rotation * axisRotation;
rigidbody.MoveRotation(finalRotation);

