Help with limiting turret rotations
Hi guys,
I am having an issue with understanding some rotations and limiting them.
Here is my use case:
I have a ship that has a turret on it. I want this turret to turn towards an arbitrary "target".
That part is simple enough, do the old
lookAtTarget = targetPosition - transform.position;
transform.rotation = Quaternion.LookRotation(lookAtTarget);
But here comes the issues. I want to limit this rotation in several ways:
I want to limit the rotation of this turret to only the local plane of the ship, so that it doesnt rotate up and down when there are waves. (This I have also managed to get working via several work arounds, but solutions seem fragile).
I want to limit the local rotation of the turret such that it cannot rotate back towards the ship itself. This I managed to also get working but only using global rotations, not local, such that it only works when the ship is facing the original orientation. Furthermore I would ideally want to set up these rotations in a way that I can input it as a rotation value from neutral position. Example, the game starts with the turret pointing forwards, and then it can do +/- 120 degrees rotation from that, nothing more.
I have tried many different iterations and looking at many different threads on the internet, and they usually only deal with part of my issues. My lack of understanding of quaternions to localeulerangles is mainly to blame I think.
I would appreciate any help or advice you are able to offer me :)
For reference here is my current and broken iteration of the code that only works when stationary. Also the "50" and "300" values were some values I have put in there learned through debugging the angle variable in the code. But I would dearly want these swapped with a "maxRotation" value that I can input to each turret.
targetPosition = hit.point;
lookAtTarget = new Vector3(targetPosition.x - transform.position.x, 0, targetPosition.z - transform.position.z);
var targetRotation = Quaternion.LookRotation(lookAtTarget);
var angle = targetRotation.eulerAngles.y;
if (angle < 50.0f)
{
Vector3 tmp = targetRotation.eulerAngles;
tmp.y = 50.0f;
targetRotation.eulerAngles = tmp;
}
if (angle > 300.0f)
{
Vector3 tmp = targetRotation.eulerAngles;
tmp.y = 300.0f;
targetRotation.eulerAngles = tmp;
}
if (((angle >= 50.0f) && (angle <= 300.0f)))
{
// using Lerp instead of Slerp so it doesnt go by the shortest distance (and thus rotating past its limits)
float rot = Mathf.Lerp(transform.rotation.eulerAngles.y, targetRotation.eulerAngles.y, rotationSpeed * Time.deltaTime);
transform.rotation = Quaternion.Euler(0, rot, 0);
}
transform.rotation = Quaternion.Slerp(transform.rotation, playerRot, rotationSpeed * Time.deltaTime);
Thanks for your time!