- 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.
Your answer