Hi;
I have a UI button and it moves around a circular UI object according to user mouse drag input. I want to know how do I detect if the user moves the button clockwise of counter clockwise? I did a little research and I guess it can be done by using Dot product. I tried a bit bu no luck.
So, how can I do that?
Thanks.
Here is what I tried;
First I get the initial position of the input;
public void OnPointerDown(PointerEventData eventData)
{
initialMousePosition = eventData.position;
}
Then when the user drag the button;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
innerCircleController.GetComponent<RectTransform>(),
eventData.position,
eventData.pressEventCamera,
out clickPos
))
{
// Get the input direction
Vector2 v2 = clickPos - initialMousePosition;
print(v2);
Vector2 direction = v2 / v2.magnitude;
// Dot product the direction and the circular UI object's direction.
float f = Vector2.Dot(direction, -innerCircleRectTransform.up);
if(f > 0)
print("Clockwise");
else
print("CounterClockWise");
}
I would probably work this out using Mathf.Atan2(y,x) to get the current angle and comparing it to the previous angle.
1 Like
Where should I do this exactly? In OnDrag event, like this;
float atan2 = Mathf.Atan2(clickPos.x, clickPos.y);
if (Mathf.Atan2(clickPos.x, clickPos.y) > atan2)
{
print("Clockwise");
}
else
print("Counter Clockwise");
Only responding to point out that your Xs and Ys are reversed for Mathf.Atan2 
You’ve got the basic idea. You need to keep the previous angle, and compare it to the new angle. But you’re going to run into awkward places where degrees wrap around (which I think is -pi and pi, though it might be 0 and 2*pi; I’m not sure exactly what the range of Atan2 is).
So instead, I would keep the last mouse position (relative to center) and compare it to the new one (also relative to center), using this handy dandy function:
/// <summary>
/// Returns the signed angle between this 2D vector and another.
/// (This is unlike Vector2.Angle, which always returns the
/// absolute value of the angle.)
/// </summary>
/// <returns>The signed angle, in degrees, from A to B.</returns>
/// <param name="a">Vector this was called on.</param>
/// <param name="b">Vector to measure the angle to.</param>
public static float SignedAngleTo(this Vector2 a, Vector2 b) {
return Mathf.Atan2( a.x*b.y - a.y*b.x, a.x*b.x + a.y*b.y ) * Mathf.Rad2Deg;
}
This won’t have any wrap-around points, at least not that you could reach while dragging a mouse.
Then what I’d do with that is simply add it to a running total, adding up all of those little one-frame angles the whole time the mouse is down. At the end, this total should be strongly > 0 if they went one way, and < 0 if they went the other. If it’s close to zero then they did something funky that you may want to ignore.
@JoeStrout Thank you for your reply. Is there a specific purpose for make the SignedAngleTo function as an extension method ?
Just convenience. Make it a non-extension method if you prefer.
@JoeStrout I use this function with passing initialPosition and currentPosition, and adding it to total but the total always increasing whatever I keep rotating to clockwise or counterclockwise
I guess I did it wrong?
In OnDrag event;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
innerCircleController.GetComponent<RectTransform>(),
eventData.position,
eventData.pressEventCamera,
out clickPos
))
{
total += SignedAngleTo(initialMousePosition, clickPos);
}
I’m guessing, based on the variable name, that “initialMousePosition” is only the initial mouse position. I didn’t say to compare the current position to the initial position; I said to compare it to the last position. You want to add up the changes from frame to frame.
Also, when things don’t work the way you expect, remember to use Debug.Log to check your assumptions!
I have an object spinning on its axis how can I determine that the spinning motion is “CW” or “CCW”.
What’s making it spin? And if this is in 3D, then “CW” or “CCW” from what point of view?
A joystick is making it a spin. Yes, It is in 3D and the view is TopDown.
A joystick can’t make something spin. You must have code that makes it spin (perhaps in response to a joystick). That’s what I’m trying to get you to consider. Look at that code; it is already programmed to make the object spin CW or CCW from a top-down point of view. That’s almost certainly the easiest place to hook in and report to whatever other code wants to know about it.
Just tell me if an object is rotating on its own y-axis then how can we calculate.