I've done some reasearch on this, but nothing seem to work in a proper manner. Hopefully someone can shed light on what I'm doing wrong.
In this 2D Unity game I'm working on I want the cannons to follow the mouse and rotate around the z-axis. The current code does exactly that, but I would also like to clamp the rotation.
Vector3 dir = Camera.main.ScreenToWorldPoint (Input.mousePosition);
Quaternion targetRotation = Quaternion.LookRotation(transform.position - dir.normalized, Vector3.forward);
targetRotation.x = 0;
targetRotation.y = 0;
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed * 10);
I have tried using if
-statements to limit rotation:
if(eulerAngle > 65 && eulerAngle < 295) //pseudo code
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, Time.deltaTime * rotationSpeed * 10)
This works, but locks the barrel of the cannon at either 65 or 295 degrees. I've had no luck using if
statements to "unlock" the barrel rotation.
I've also tried a similar statement using Quaternions:
float amountToRotate = Quaternion.Angle (transform.rotation, targetRotation);
I guess, due to the way quaternions work, the angle increases even by moving further away from the target. Similar to numbers on the complex plane?
The mathf.clamp
function gave me no luck at all.
There's probably an easy fix to all these solutions to the problem, but I just can't seem to work it out.
Edit: I would prefer to use mathf.clamp
as that seems to be the "cleanest" solution.
The problem seems to be in your if
state logic.
Lets break it up in some logical blocks:
If this is not the case that means the value is under or equal to 65 and the if
wont run. In the next block (if the value is over 65)
if this is not the case that means the value is bigger or equal to 295.
First off all I would advice to turn your if statement to include equal to
if(eulerAngle >= 65 && eulerAngle <= 295)
This gives us a few checks less to think about. Now we know, if your cannon rotation freezes it is because the angle is lower then 65 ( < 65) or higher then 295 (> 295).
For the if statement to be able to continue you will want the value to be in between the values again, because you added the = check to the values as well. You can now just set them to 65 or 295 according to which one is out of range. Sample to give you an idea:
else if( eulerAngle < 65)
eulerAngle = 65;