Reputation: 365
So I have an object that has a handle attached to it, the player is supposed to rotate this handle. For that, I'm taking in the horizontal and vertical axis of a controllers analogue stick and transform these values into degrees, which I then use to rotate the object.
The problem is that I can't seem to completely block out the possibility of rotating the handle counterclockwise, as the player is only supposed to rotate it clockwise. What happens is that every couple of frames while I try rotating counterclockwise it detects a clockwise rotation, executing my according code, even though I was rotating counterclockwise consistently.
The principles I use to determine which direction the rotation is going is done by comparing the input angle of the last frame to the current input angle, like:
// Variant 1:
var inputAngle = Mathf.Atan2(x, y) * Mathf.Rad2Deg;
float angleDifference = inputAngle - previousAngle;
if (angleDifference > 180f) angleDifference -= 360f;
if (angleDifference < -180f) angleDifference += 360f;
if (Mathf.Sign(angleDifference).Equals(-1))
{
// Counterclockwise rotation
}
else
{
// Clockwise rotation
}
// ...
previousAngle = inputAngle;
In another attempt, I tried to do this comparison by simply checking if my current angle is larger than my previous one while having the input transformed in a 0° to 360° range and also handling the overflow from going back to 0° from 360°, which did not work consistently either.
So I tried to see what the values are giving in this faulty case, but what this told me was simply that the values are not as I expected them to be, as the current angle should be smaller than the previous one while rotating counterclockwise, in those cases and I can't figure out why or how to prevent it?
So I guess in the end my question would be how can I consistently prevent a player from rotating counterclockwise by reading a controller's analogue stick input.
Upvotes: 0
Views: 255
Reputation: 20269
I would use Vector3.SignedAngle to get the to-from angle around the forward axis. Then if the angle is negative, it's clockwise; positive is counter-clockwise:
Vector3 previousPos;
Vector3 GetPos()
{
/* return current controller position, between (-1,-1,0) and (1,1,0) */
}
void Awake() { previousPos = previousPos; }
void Update()
{
Vector3 curPos = GetPos();
float deltaAngle = Vector3.SignedAngle(previousPos, curPos, Vector3.foward);
// If you want to clamp the speed
// float maxSpeed = 180f; // max rotational speed = 180 degrees per second
// deltaAngle = Mathf.Clamp(deltaAngle/Time.deltaTime, -maxSpeed, maxSpeed)
// * Time.deltaTime;
bool isClockwise = deltaAngle < 0;
bool isCounterClockwise = deltaAngle > 0;
if (isClockwise)
{
// do stuff when motion is clockwise
}
else if (isCounterClockwise)
{
// do stuff when motion is counter clockwise
}
else
{
// do stuff when no rotational motion occurs
}
previousPos = curPos;
}
Upvotes: 1