Despite this being what I consider a simple and common problem, I struggled greatly to find somewhere that adequately described the solution. So here's how I handled it!
Things to note:
-Angles are in degrees (Most math libraries use radians, but I find degrees easier to assign initial values to, so we'll assume all Math functions we use take and return degrees)
-0 degrees is straight right, and the range of angles is 180 (counter clockwise) -> -180 (clockwise)
First of all, you'll need a helpful function called WrapAngle. Monogame has this by default in the MathHelper class, but in essence it does the following:
Alright, so whenever we modify an angle, we need to feed it through WrapAngle.
Next step, is to get our compared value. facingAngle is your current facing, and targetAngle is . . . well, the angle you're turning towards.
We now use this, along with the turningSpeed of the entity to update the facing position. We do a quick check to make sure this direction is actually the shortest.
Aaaaand done! Put this in your update loop, and your entity will always turn to a given angle, taking the shortest
public float WrapAngle(float angle) { while (angle > 180) { angle -= 360; } while (angle < -180) { angle += 360; } return angle; }
Alright, so whenever we modify an angle, we need to feed it through WrapAngle.
Next step, is to get our compared value. facingAngle is your current facing, and targetAngle is . . . well, the angle you're turning towards.
float compareAngle = WrapAngle(targetAngle - facingAngle);
We now use this, along with the turningSpeed of the entity to update the facing position. We do a quick check to make sure this direction is actually the shortest.
facingAngle = facingAngle + Math.Min(turningSpeed, Math.Max(-turningSpeed, compareAngle));
Aaaaand done! Put this in your update loop, and your entity will always turn to a given angle, taking the shortest
No comments:
Post a Comment