- Home /
Rotations problem..
I want to rotate a cube smoothly with 45 degress each time, so if I click on the cube it snaps to 45 degrees and then to 90 degrees and so on till 360. What the problem is it goes not exactly to 45 degrees but 43.4 on the rotation and I want that it goes exactly to 45.
What I tried:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class useObject : MonoBehaviour {
float thisStep = 0f;
GameObject lastHit;
void Start () {
Screen.lockCursor = true;
}
void Update ()
{
if(thisStep == 0 && lastHit != null)
{
float rot = Mathf.RoundToInt(lastHit.transform.rotation.eulerAngles.x);
print("r=" + rot);
if(rot > 10 && rot < 45) // 0
{
lastHit.transform.rotation = Quaternion.Euler(new Vector3(0,0,0));
lastHit.transform.Rotate(new Vector3(Mathf.LerpAngle(0f,90f,Time.deltaTime),0f,0f));
}
else if(rot > 45 && rot < 135) // 90
{
lastHit.transform.rotation = Quaternion.Euler(new Vector3(0,90,0));
lastHit.transform.Rotate(new Vector3(Mathf.LerpAngle(0f,90f,Time.deltaTime),0f,0f));
}
else if(rot > 135 && rot < 225) // 180
{
lastHit.transform.rotation = Quaternion.Euler(new Vector3(0,180,0));
lastHit.transform.Rotate(new Vector3(Mathf.LerpAngle(0f,90f,Time.deltaTime),0f,0f));
}
else if(rot > 225 && rot < 315) // 270
{
lastHit.transform.rotation = Quaternion.Euler(new Vector3(0,270,0));
lastHit.transform.Rotate(new Vector3(Mathf.LerpAngle(0f,90f,Time.deltaTime),0f,0f));
}
else // 0
{
lastHit.transform.rotation = Quaternion.Euler(new Vector3(0,0,0));
lastHit.transform.Rotate(new Vector3(Mathf.LerpAngle(0f,0f,Time.deltaTime),0f,0f));
}
print ("hallo2=" + lastHit.transform.rotation.x);
}
Ray raycast = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit raycasthit = new RaycastHit();
if (Physics.Raycast(raycast, out raycasthit, 1000.0f) && Input.GetMouseButton(0) && thisStep < 360)
{
switch(raycasthit.collider.name)
{
case "Deel1":
case "Deel2":
case "Deel3":
Vector3 rot = new Vector3(Mathf.LerpAngle(0f,90f,Time.deltaTime),0f,0f);
if(thisStep + rot.x <= 360)
{
lastHit = raycasthit.collider.gameObject;
raycasthit.collider.transform.Rotate(rot);
thisStep += rot.x;
}
else if(thisStep + rot.x == 360)
{
lastHit = raycasthit.collider.gameObject;
raycasthit.collider.transform.Rotate(rot);
thisStep -= rot.x;
}
break;
default: print("Unhandled raycastHit " + raycasthit.collider.name); break;
}
}
else if(Input.GetMouseButtonUp(0))
{
thisStep += 0;
}
}
}
Comparing your words to your code, I'm confused by what you want to accomplish. Do you want an immediate rotation to 45 degrees or, or do you want a quick snap (i.e. rotation takes a few frames)? Which axis do you want to rotate around? What do you want to happen when the object reaches 360 degrees...stop and do nothing or reverse direction?
Some thoughts from looking at your code. Transform.Rotate() is relative. It rotates by the specified amount from a starting angle. Assigning Quaternion's to transform.rotation is absolute. You are assigning a specific rotation to the object. Any of the Lerp methods (including LerpAngle() need a parameter that increment/decrements over time in the range of 0 to 1. Time.deltaTime is the time since the last frame and remains fairly constant.
What I want is when you click on the target it rotates slow and smooth to 90 degrees on the x- as of the target and if I click again it goes form 90 degrees to 180 also slow and smooth and so on till 360. And then from 360 the same rythm back. from 0/90/180/270/360 to 360/270/180/90/0
Can u tell me how or where I can find/learn them, because I am really interested.
Thanks!
Answer by robertbu · Jan 28, 2013 at 09:48 PM
I recommend making the code that rotates the object a component of that object. You are using global code attached to some other objects you want to rotate. With that configuration, if you click on one object and start it rotating and then click on a second object object and start it rotating, the first object will stop rotating before the rotation is complete because you are reassigning lastHit. Attach the code below to any object you want to rotate by 90 degrees.
public class RotateBy90: MonoBehaviour {
public float maxDegreesPerSecond = 30.0f;
private int iRotation = 0; // Rotation = 90 * iRotation
private int iInc = 1;
private Quaternion qTo;
void Start() {
qTo = transform.rotation;
}
void OnMouseDown() {
iRotation += iInc;
if (iRotation == 0)
iInc = 1;
if (iRotation == 4)
iInc = -1;
qTo = Quaternion.Euler (iRotation * 90.0f, 0.0f, 0.0f);
}
void Update() {
transform.rotation = Quaternion.RotateTowards (transform.rotation, qTo, maxDegreesPerSecond * Time.deltaTime);
}
}
it works but again the values of x are from 0 to 90 and then to -5.008956e-06 then to 270 and as last to -5.008956e-06.
But what I want is that it goes from 0/90/180/270/360 in that way.
Thanks btw!
-5.008956e-06 is .000005008956...essentially 0.0. So the rotation vector is (0,180,180) which orients the cube the same as (180,0,0). This is the kind of thing you will get when working with Quaternions. The code does rotate by 90 degrees. This is not the problem in your code above. A setting of 43.4 is a fair ways away from 45 degrees. If you really need the values to read (180,0,0) there are other ways to rotate the cube, but the code will be more complex including dealing with the 360/0 boundary.