# How to adjust a direction Vector to say within a certain angle?

I’m making a 2D top-down view game. The sprite moves and rotates where I click the mouse on the screen. But I don’t want the sprite rotating almost instantly when I click the mouse on its opposite side. Basically, i want something like this

The Green triangle is the Sprite, with the red arrow representing its “forward” position (which equals to transform.up in-game). The blue stars are the mouse-clicks I want to be recognised. The grey stars I want the code to interpret as if I clicked the mouse on the edge of the red angle lines. Basically limiting how far “back” the sprite can see its direction.

This is a simplification of the code that handles the sprite rotation

``````Vector3 lookDir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
if(Input.GetMouseButton(0)) {
Quaternion rotation = Quaternion.LookRotation(forward: Vector3.forward, upwards: lookDir);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime);
}
``````

And this code works perfectly for any movement that happens in front of the sprite, I just don’t like how quickly it can do a 180 if I hold the mouse button down. Changing the rotation speed down to a very small number doesn’t seem to do anything.

I’ve tried using the Vector3.angle function to see what’s the optimal angle range, but I’m not sure how to limit lookDir to my hypothetical “red lines” in the drawing.

I haven’t made a 2D game in a while so feel free to correct me if I’m wrong but I can’t think of a reason to use Quaternions in a 2D game except for very fancy 2.5D camera effects. I know this isn’t your question but if you’re like most people (including myself) find Quaternions difficult to visualise then I’d advise moving towards simpler 2D rotations.
_
For 2D rotations you only need to worry about the z component of your transform rotation. I haven’t double checked but I believe this is set by

transform.LocalEulerAngles = new Vector3(0f,0f, newRotationValue);
Or

transform.LocalEulerAngles += new Vector3(0f,0f, rotationDelta); Or

transform.LocalEulerAngles = new Vector3(0f,0f, Mathf.Lerp(CurrentAngle, targetAngle, changeRate * Time.deltatime));

I also don’t think you’ll need to use Slerp for this; you can use Lerp instead.
_
Using 2D rotations is if you calculate the angle from player’s forward direction you’ll get an number between -180 and +180 (using Vector2.SignedAngle, NOT Vector2.Angle).

In your specific case if the signed angle is below -120 or above +120 then you can remove the excess value and set that hard limit for the player.
_
You may encounter some trouble when the player rotates from say +175 degrees to -175 degrees (like a sudden spin that’s excessively fast). the simplest way to solve this is to add an if statement to see if the difference between the currentAngle and targetAngle is more than 180 degrees and if it is either add or deduct 360 degrees from your player’s currentAngle or targetAngle.
__
Example - player is at -179 degrees, target angle is +150 degrees (a 329 degree angle change!)

As the player’s angle is negative add 360 degrees, then the player is at +181 degrees, which is now only a 31 degree change.

Here is a quick fix:

``````  Camera camera;
// Start is called before the first frame update
void Start()
{
//Camera.main shouldn't be used in Update as it searching through all scene
//gameObjects to find the Camera!
camera = Camera.main;
}

// Update is called once per frame
void Update()
{
Vector3 clickPosition = camera.ScreenToWorldPoint(Input.mousePosition);
Vector3 transformPosition = transform.position;
//We need make sure the mouse click is on the same plane
clickPosition.z = transformPosition.z;
Vector3 lookDir = clickPosition - transformPosition;

if (Input.GetMouseButton(0))
{
var angle = Vector3.SignedAngle(lookDir, Vector3.left, Vector3.forward);
if (angle < -30f && angle > -150f) return;

Quaternion rotation = Quaternion.LookRotation(forward: Vector3.forward, upwards: lookDir);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime);
}
}
``````