Reputation: 153
I'm writing a C# script in Unity, trying to make a spaceship in my top-down game rotate to face the mouse position. For some reason I'm having trouble, though, and I'm not sure what the problem is. Basically, if the ship is facing a small positive angle, say 10 degrees, and the mouse is at 350 degrees, the ship SHOULD rotate clockwise because that's the faster way to go. The ship rotates the correct direction except in this one case (when your ship is above the horizontal and your mouse is below).
This is a visual example of what I want in this case, vs what happens. Link: https://i.sstatic.net/V9EaC.png
This is the method which is supposed to return true if a counterclockwise rotation would be faster than a clockwise rotation.
bool turnCounterFaster() {
//Returns true if turning left would be faster than turning right to get to the ideal angle
float targetAngle = getAngleToMouse ();
float currentAngle = rigidbody2D.rotation;
while (currentAngle > 360f) {
//Debug.Log ("Current angle was "+currentAngle);
currentAngle -= 360f;
//Debug.Log ("now is:"+currentAngle);
}
if (targetAngle < currentAngle) {
//It's possible the target angle is a small angle, if you're a large angle it's shorter to turn counterclokwise
float testDiff = Mathf.Abs((targetAngle+360) - currentAngle);
if(testDiff < Mathf.Abs (targetAngle-currentAngle)){
//Turning counter clockwise is faster
//Debug.Log ("(false) edge case Current "+currentAngle+" target "+targetAngle);
return false;
}
//Debug.Log ("(true) target < current Current "+currentAngle+" target "+targetAngle);
return true;
}
return false;
}
And this is the method that gets the angle between the player and the mouse. These scripts are both attached to the player object.
float getAngleToMouse(){
Vector3 v3Pos;
float fAngle;
// Project the mouse point into world space at
// at the distance of the player.
v3Pos = Input.mousePosition;
v3Pos.z = (transform.position.z - Camera.main.transform.position.z);
v3Pos = Camera.main.ScreenToWorldPoint(v3Pos);
v3Pos = v3Pos - transform.position;
fAngle = Mathf.Atan2 (v3Pos.y, v3Pos.x) * Mathf.Rad2Deg;
if (fAngle < 0.0f)
fAngle += 360.0f;
//Debug.Log ("ANGLE: "+fAngle + " and ship angle: "+rigidbody2D.rotation);
return fAngle;
}
And this is the script that actually causes the ship to turn in either direction. The addTurnThrust method appears to be working correctly, and I've tested it with keyboard input and noticed no problems.
if (turnCounterFaster() == false) {
addTurnThrust(turnAcceleration,true);
} else {
addTurnThrust(-1*turnAcceleration,true);
}
I'm sure there's something incredibly obvious but I'm at my witts end here. Any advice would be greatly appreciated!
Upvotes: 3
Views: 3933
Reputation: 9266
Calculate sin(currentAngle - targetAngle)
. If it is positive, currentAngle needs to move clockwise. If the sine is negative, currentAngle needs to move counterclockwise. If it's zero, then the two angles are either the same or 180° opposite. This works even if the angles aren't normalized to [0,360).
Upvotes: 4