Transform.Rotate() seems to be doing "extra" rotations, and I'm not sure why. Consider the following code, which is attached to a flattened cube (like a plane, though I will call it a board). It allows the user to tilt the board using the arrow keys. The tilt is constrained, though, so flipping the board is impossible. Code (csharp): var tilt_rate = 100.0; function FixedUpdate () { if (Input.GetKey("left") (transform.localEulerAngles.x > 350 || transform.localEulerAngles.x < 15) ) { transform.Rotate(Vector3.left * Time.deltaTime * tilt_rate); } // if right if (Input.GetKey("right") (transform.localEulerAngles.x > 345 || transform.localEulerAngles.x < 10) ) { transform.Rotate(Vector3.right * Time.deltaTime * tilt_rate); } // if right if (Input.GetKey("down") (transform.localEulerAngles.z > 350 || transform.localEulerAngles.z < 15) ) { transform.Rotate(Vector3.back * Time.deltaTime * tilt_rate); } // if right if (Input.GetKey("up") (transform.localEulerAngles.z > 345 || transform.localEulerAngles.z < 10) ) { transform.Rotate(Vector3.forward * Time.deltaTime * tilt_rate); } // if right if (Input.GetKey("space")) { transform.localRotation = Quaternion.identity; } // if space } // FixedUpdate() If the direction keys are continuously pressed in rotational order (up, right, down, left, up, right, etc.) then the board will rotate through the Y axis. Visually this looks like the board rotating around on a lazy Susan, or having the camera rotate around the board. Does anyone know why this Y axis drift is occuring, and what I can do to prevent it? Tom
Be very careful about using euler angles. Changing one can easily change the other. I recommend using a transform's forward vector to determine stuff about where it's facing rather than euler angles.
Can't see exactly where your rotations go wrong, but some suggestions to make the whole script a lot simpler 1. store x and y rotation as a float Code (csharp): var x = 0.0; var y = 0.0; 2. Every frame, add x and y by Input.GetAxis("Horizontal") / Input.GetAxis("Vertical"). Code (csharp): x += Input.GetAxis("Horizontal") * Time.deltaTime * speed; 3. Then clamp x and y using Mathf.Clamp 4. Apply the rotation using Code (csharp): transform.rotation = Quaternion.identity; transform.Rotate(x, 0, y);
I'm careful not to modify the Euler angles (here) -- just wanted to know the rotation relative to the parent. I did see the forward vector code in the physics demo (making the car untopple itself), but didn't quite follow how that was working. (I didn't know how to interpret "transform.rotation * Vector3.fwd". A 1x4 vector times a 1x3 vector? But then, my matrix algebra is almost 20 years old...) To solve the Y axis rotation problem I ended up fixing the Y rotation at the end of the script. Code (csharp): transform.localEulerAngles.y = 0; (Okay, it's fixing an Euler angle, but it looks safe. :wink: ) The GetAxis() example certainly looks more straightfoward. Are scripts atomic? That is, is there any chance a script could be interrupted between these two lines? Code (csharp): transform.rotation = Quaternion.identity; transform.Rotate(x, 0, y); Tom
Unity will never interrupt a script function execution on it's own. But you can tell unity to pause execution using coroutines. Coroutines are a great concept. They can simplify code a lot when you have to deal with behaviours/events over time. Which games happen to do a lot. http://www.otee.dk/Documentation/ScriptReference/index.html#The Yield Statement
That's a quaternion 'multiplied' by a vector, which is the usual notation for "rotate this vector by this quaternion". So, for example: Code (csharp): localForwardVector = transform.rotation * Vector3.forward; Quaternions are essentially 4D vectors, but you may as well ignore that detail, and just concentrate on thinking of them as rotations which can be used to rotate vectors and objects.
I've just been informed by Joe that our Lerps all clamp between 0 and 1. Hence you don't need to worry about the last step.
Joachim: Thanks for the info on script execution. NCarter: Thanks -- I'm familiar with quaternions in general, but the special notation wasn't obvious. After seeing your post I found the notation documented: http://otee.dk/Documentation/ScriptReference/Quaternion.html#operator * I'm assuming it is also the same as QuatRotateVector(Quat, Vector) in the Unreal Engine. (http://wiki.beyondunreal.com/wiki/Quaternion) Tom