I am sure this is an issue due to quaternions or the like, but…
In an attempt to get a jump on something, I was working on a snippet of code, and was trying to rotate a cube with a script so that the cube would rotate 180* every time the user clicked the cube, but couldn’t effect the cube while it was rotating.
At first I thought I’d just lerp the axis, and protect the cube with an If() until it was done rotating.
cube.transform.rotation.AXIS(x,y,or z) = Mathf.Lerp(originalAngle, targetAngle, (Time.time - startTime) * turnSpeed);
if ((targetAngle - cube.transform.rotation.AXIS(x,y,or z)) < 3.0 || (targetAngle - cube.transform.rotation.AXIS(x,y,or z)) > 357.0 )
(Where "AXIS(x,y,or z)" is the axis of choice. e.g.: cube.transform.rotation.y)
It works on the y-axis, but on the x- and z-axes, the way that Unity interprets the rotation into the discreet axes causes problems.
To take the x for example - If you start with transform = (0,0,0) and try to rotate on the x through to tranform = (180, 0,0), when x > 90*, Unity resets y z to 180* and x counts DOWN from 90* back to 0*.
Ratz.
If however, I accept this new transform rotation of 0,180,180 as teh NEW start position for the second rotation and try to lerp again from x=0 to x=180, Unity pops the transform rotation back to 0,0,0 from 0,180,180 just by using x = 0. So - somewhere Unity is remembering (even tho’ it’s displaying and using 0,180,180) that I was only effecting the x-axis, and reverts back to what it was…
The crux to this problem is trying to test when the operation is finished, and how to do it again on a second click. The first time always works fine in the ROTATE lerp. What happens tho’ is it never detects the end of the rotation, because it never reaches it’s goal position.
If (as is shown below), I just end the rotation based on time, I can’t get the second rotation target to work correctly because of the reset of the rotation.
I’ve tried the transform, quaternions, euler angles… pretty much all shots in the dark.
Can anyone suggest a better way of doing this?
var cube : GameObject;
var turnSpeed : float = 2.0;
private var startTime : float;
private var originalAngle : float;
private var targetAngle : float;
private var canRotate : boolean = true;
private var rotating : boolean = false;
function OnMouseUp () {
if (canRotate) {
canRotate = false;
startTime = Time.time;
originalAngle = cube.transform.rotation.x;
targetAngle = cube.transform.rotation.x + 180;
rotating = true;
}
}
function Update () {
if (rotating) {
cube.transform.rotation.x = Mathf.Lerp(originalAngle, targetAngle, (Time.time - startTime) * turnSpeed);
// if ((targetAngle - cube.transform.rotation.AXIS(x,y,or z)) < 3.0 || (targetAngle - cube.transform.rotation.AXIS(x,y,or z)) > 357.0 )
if ((Time.time - startTime) > 0.55) {
cube.transform.rotation.x = Mathf.Round(targetAngle);
canRotate = true;
rotating = false;
}
}
}
This is the unedited code that’s mid-test with some other attempts including the euler angles… Pretty much junk:
var cube : GameObject;
var turnSpeed : float = 2.0;
private var startTime : float;
private var originalAngle : float;
private var targetAngle : float;
private var canRotate : boolean = true;
private var rotating : boolean = false;
function OnMouseUp () {
Debug.Log ("Rotating: " + rotating);
Debug.Log ("canRotate: " + canRotate);
if (canRotate) {
canRotate = false;
startTime = Time.time;
originalAngle = cube.transform.rotation.x;
targetAngle = cube.transform.rotation.x + 180;
// targetAngle = cube.transform.rotation.eulerAngles + Vector3(0, 180, 0);
rotating = true;
}
Debug.Log ("currentAngle: " + cube.transform.rotation.x);
Debug.Log ("targetAngle: " + targetAngle);
// Debug.Log ("currentAngle: " + cube.transform.rotation.y);
// Debug.Log ("targetAngle: " + targetAngle);
Debug.Log ("------------------------------------------------------");
}
function Update () {
if (rotating) {
cube.transform.rotation.x = Mathf.Lerp(originalAngle, targetAngle, (Time.time - startTime) * turnSpeed);
// cube.transform.rotation = Quaternion.AngleAxis(Mathf.Lerp(originalAngle, targetAngle, (Time.time - startTime) * turnSpeed), Vector3.right);
if ((Time.time - startTime) > 0.55) {
cube.transform.rotation.x = Mathf.Round(targetAngle);
// if ((targetAngle - cube.transform.rotation.x) < 3.0 || (targetAngle - cube.transform.rotation.x) > 357.0 ) {
// cube.transform.rotation.x = 0.0;
// cube.transform.rotation.x = Mathf.Round(targetAngle);
// if ((targetAngle.y - cube.transform.rotation.eulerAngles.y) < 3.0 || (targetAngle.y - cube.transform.rotation.eulerAngles.y) > 357.0 ) {
// cube.transform.rotation.eulerAngles.y = Mathf.Round(targetAngle.y);
canRotate = true;
rotating = false;
}
}
}