- Home /
Rotate A dial with circular motions
This has been the bane of my existence for the past 2 weeks and have not been able to get it to do what I want. I have the dial turning correctly, But using the mouse or touch is not very intuitive. I can turn the dial by dragging the mouse to the left or right on the horizontal. but when I try and make circular motions it does not work.
Any help would be appreciated.
Is this a GUI object (called from OnGUI) or an object in 3D space?
Answer by musoufan91 · Aug 30, 2013 at 01:40 AM
Solution if object is rotating on the Z. Most of the credit goes to robertbu.
private Quaternion originalRotation;
private float startAngle = 0;
public void Start()
{
originalRotation = this.transform.rotation;
}
public void InputIsDown()
{
#if UNITY_IPHONE || UNITY_ANDROID
originalRotation = this.transform.rotation;
Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 vector = Input.GetTouch(0).position - screenPos;
startAngle = Mathf.Atan2(vector.y, vector.x) * Mathf.Rad2Deg;
//startAngle -= Mathf.Atan2(transform.right.y, transform.right.x) * Mathf.Rad2Deg; // uncomment to pop to where mouse is
#else
originalRotation = this.transform.rotation;
Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 vector = Input.mousePosition - screenPos;
startAngle = Mathf.Atan2(vector.y, vector.x) * Mathf.Rad2Deg;
//startAngle -= Mathf.Atan2(transform.right.y, transform.right.x) * Mathf.Rad2Deg; // uncomment to pop to where mouse is
#endif
}
public void InputIsHeld()
{
#if UNITY_IPHONE || UNITY_ANDROID
Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 vector = Input.GetTouch(0).position - screenPos;
float angle = Mathf.Atan2(vector.y, vector.x) * Mathf.Rad2Deg;
Quaternion newRotation = Quaternion.AngleAxis(angle - startAngle , this.transform.forward);
newRotation.y = 0; //This and the line below, may need to be changed depending on what axis the object is rotating on.
newRotation.eulerAngles = new Vector3(0,0,newRotation.eulerAngles.z);
this.transform.rotation = originalRotation * newRotation;
#else
Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 vector = Input.mousePosition - screenPos;
float angle = Mathf.Atan2(vector.y, vector.x) * Mathf.Rad2Deg;
Quaternion newRotation = Quaternion.AngleAxis(angle - startAngle , this.transform.forward);
newRotation.y = 0; //see comment from above
newRotation.eulerAngles = new Vector3(0,0,newRotation.eulerAngles.z);
this.transform.rotation = originalRotation * newRotation;
#endif
}
Answer by robertbu · Aug 26, 2013 at 11:06 PM
I've answered this question several times with different solutions for both GUI.DrawTexture() and for object in 3D space. Here is one of those links:
http://answers.unity3d.com/questions/389586/rotate-gui-texture-by-touch.html
The solution for an object in world space will depend on the natural orientation of the object. Here is a solution that works when the camera is looking at the back of the object. In particular it works with a plane created by the Unity Wiki CreatePlane editor script with the plane in vertical orientation:
#pragma strict
var startAngle = 0.0;
function On$$anonymous$$ouseDown() {
var screenPos = Camera.main.WorldToScreenPoint(transform.position);
var vec = Input.mousePosition - screenPos;
startAngle = $$anonymous$$athf.Atan2(vec.y, vec.x) * $$anonymous$$athf.Rad2Deg;
startAngle -= $$anonymous$$athf.Atan2(transform.right.y, transform.right.x) * $$anonymous$$athf.Rad2Deg;
}
function On$$anonymous$$ouseDrag() {
var screenPos = Camera.main.WorldToScreenPoint(transform.position);
var vec = Input.mousePosition - screenPos;
var angle = $$anonymous$$athf.Atan2(vec.y, vec.x) * $$anonymous$$athf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle - startAngle , Vector3.forward);
}
Thank you. When I added it in the dial became backwards but worked. I fiddled with it and if you add
public void Start()
{
originalRotation= this.transform.rotation;
}
then
this.transform.rotation = originalRotation * Quaternion.AngleAxis(angle - startAngle , this.transform.forward);
It works.
I am going to modify it for touch then post it here so others can grab it.