- Home /
Advanced rotation on 2D circle with mouse drag
Hello Unity, I need some advanced assistance to rotate a 2D circle object, no matter where the user starts to click/drag the object from. I will explain in as much detail as possible. Here is the 2D sprite image...
The forward vector for the object is in the direction of the knob at the top of the image. When the user clicks and drags the top knob around, the object rotates correctly around the Z axis. But I want the user to be able to click and drag anywhere on the image to have it rotate around the Z axis.
I want it to simulate a steering wheel. If I grab the top of a steering wheel, and turn it clock wise, then the object should turn clock-wise, and then stay at that angle of rotation when i let go. If I then grab the bottom of the steering wheel and rotate it counter clock wise, then i want to rotate in the counter clock wise direction, and when i let go, stay in that position/rotation angle.
Currently, the object will quickly rotate to face the click-drag position of the mouse. For example, say I click and drag the top knob clock wise any amount of degrees, and then let go. The object will rotate correctly and stay in that position/rotation. If I then click on the opposite side of the circle, it will quickly rotate to face the click/drag position, and then continue to rotate as i drag the mouse around. I don't want it to jump-rotate, I want to be able to rotate it around the Z axis by clicking and dragging from any spot on the object, without it jumping into rotation. So, basically, If I click on the top of the object and drag in the right direction, I want the object to rotate clock wise around the Z Axis. If I click on the bottom of the object and drag in the right direction, I want the object to rotate counter clock wise around the Z axis, without any fast jump-rotation happening.
Here is the code I have right now....
public void On_Drag(Gesture _Gesture)
{
if (_Gesture.pickedObject == gameObject)
{
SpinnerScreenPoint = Camera.main.WorldToScreenPoint(gameObject.transform.position);
GesturePoint.x = _Gesture.position.x;
GesturePoint.y = _Gesture.position.y;
SpinnerScreenPoint = (GesturePoint - SpinnerScreenPoint);
RotationAngle = (Mathf.Atan2(SpinnerScreenPoint.y, SpinnerScreenPoint.x) * Mathf.Rad2Deg - 90);
}
}
void Update()
{
gameObject.transform.rotation = Quaternion.AngleAxis(RotationAngle, Vector3.forward);
}
Please let me know if I need to better explain in more detail. Thank you for your help and assistance.
I think I have the same doubt as you, can you show a little more of the script because I don't understand how it works? Thanks in advance.
Unfortunately I do not have the source code anymore.
Answer by JoeStrout · Apr 22, 2015 at 05:21 PM
You're very close. All you need to do is keep a bit more data. You need:
The original angle of the wheel (get this from the transform when the gesture begins)
The original angle at which the user tapped (compute this as you're doing now, when the gesture begins)
Now, when the gesture continues (e.g. in OnDrag), you compute the NEW angle of the gesture position. This tells you how much the transform should be rotated relative to its original position. For example:
float newRot = Mathf.Atan2(SpinnerScreenPoint.y, SpinnerScreenPoint.x) * Mathf.Rad2Deg - 90;
RotationAngle = OriginalRotAng + newRot - OriginalTouchAng;
where OriginalRotAng is the original rotation of the transform, and OriginalTouchAng is the initial angle of the touch, as described above.
That's awesome, seriously! That is exactly the answer I needed. It works great now, just as I intended. You were right, I was very close, but i just need your guidance to complete this task. Cheers!
Hi I am doing somewhat similar. But the only thing I want is to restrict backward rotation. Here is the link to my question:
Can someone help me here :(
Your answer
