- Home /
Track object rotation
Hi.
I am rotating an object in FixedUpdate()
around Z axis. Now I need to track that object's rotation and store it in float rot
variable.
Problem is that i am getting rot
to be from 0 to 360. Is it possible to extend that and get it to be higher hen 360?
For example, when object is rotated for 520 degrees i get rot=520
.
Posting your rotation code would help decide what solutions would work.
Here is my rotating code:
void FixedUpdate(){
if(objekat$$anonymous$$liknut=="$$anonymous$$inute"){
mouseClickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 dir = mouseClickPos - transform.position;
angle = $$anonymous$$athf.Atan2(dir.y,dir.x) * $$anonymous$$athf.Rad2Deg;
angle-=90;
if (angle < 0.0f) angle += 360.0f;
angle = $$anonymous$$athf.Round(angle/6.0f)*6.0f;
if(angle==360) angle=0;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
hand1.transform.rotation = Quaternion.RotateTowards(hand1.transform.rotation, q, 6);
}
Answer by Scribe · Oct 14, 2014 at 12:32 PM
There is nothing internal that has that information saved, so you have to calculate it based on how many full rotations you've made previously.
Create a variable that saves the rotation from the previous frame and one that saves the rotation from the current frame, then if there difference is say, more than 270 add to your full rotations variable, if it is less than -270, minus from your full rotations variable!
Then when last frame the angle was near 0 and then it became near 360, you minus a full rotation, and vice versa.
Then you can get your rotation by doing rotation = 360*fullRotations + currentRotation;
Scribe
EDIT: based on your code you don't allow your object to rotate more than 6 degrees every frame so there would be no problem with this method, as this method only breaks if you rotate more than 270 degrees in a frame. Here's how it might look with your code:
Vector3 mouseClickPos;
float angle;
float lastAngle;
int fullRotations;
public float realAngle;
void FixedUpdate(){
mouseClickPos = Input.mousePosition;
Vector3 dir = mouseClickPos - Camera.main.WorldToScreenPoint(transform.position);
angle = Mathf.Atan2(dir.y,dir.x) * Mathf.Rad2Deg;
angle-=90;
if(lastAngle - angle > 270){
fullRotations ++;
}else if(angle - lastAngle > 270){
fullRotations --;
}
Debug.Log(360*fullRotations + angle);
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 6);
lastAngle = angle;
}
I already did try to do something like that. I was checking if object has 0 rotation and then if last angle was >0 i add full rotation and other way around. The problem is that I am rotating the object with mouse and when I pull it too fast, Update
skips some frames and it can't deter$$anonymous$$e if object had 0 rotation.
Add your current code and I can try to help some more, you could probably check if your actual input is > some value then add a full rotation!
It's working! Thanks. Just please tell me why exactly 270 degrees?
270 was an arbitrary value, I decided that it was unlikely for someone to be able to rotate something by more than 90 degrees in one frame, In your case as your rotation is limited to 6 degrees per frame, you could change 270 to 6, though I would suggest adding a bit for tolerance and floating point errors, 10 for example should work fine!
EDIT: in hindsight, it would actually make more sense to use 180, as then it checks within the same range whichever direction you go!
Answer by robertbu · Oct 14, 2014 at 03:57 PM
This kind of problem can be ugly to solve. Here is some example of one way to approach the probelm. 'rotationAmount' will be the positive or negative rotation from the original rotation.
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
private float angle = 0.0f;
private float rotationAmount = 0.0f;
void Update() {
Vector3 dir = Input.mousePosition - Camera.main.WorldToScreenPoint (transform.position);
float newAngle = Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg;
rotationAmount += Mathf.DeltaAngle (angle, newAngle);
angle = newAngle;
transform.rotation = Quaternion.AngleAxis (angle, Vector3.forward);
Debug.Log (rotationAmount);
}
}
This code assumes the initial rotation of the object is considered 0.0. In addition since 'rotationAmount' is calculated by adding lots of relative rotations, a small error will creep in due to floating point imprecision. Note that I'm converting the transform.position to a screen coordinate rather than the other way around like your code. The reason is that you code will only work (as is) for an Orthographic camera. This code will work for perspective as well.
You can divide by 360 and take the floor to get the number of positive or negative rotations if all you want is the count of rotations.
Final note. Avoid direct comparisons of floating point numbers as in this line:
if(angle==360) angle=0;