- Home /

# Limiting Vector2 directions to certain angles

Say there's a function and it receives a **Vector2** (think of some impact that may come from any direction), **another Vector2 that tells the optimal direction** and **a number of degrees** from that optimal direction that it still accepts.

If the first Vector2 matches the direction perfectly - the funciton returns it unchanged.

If it doesn't match perfectly but falls into allowed range - the function makes it smaller depending how far it is from desired direction. The farther it is - the smaller the magnitude gets.

If the vector falls out of the allowed range - the function returnse Vector2.zero.

I bet I don't know about something pretty obvious and there's something simple that solves this problem exactly.

**Answer** by Andrii
·
May 17, 2019 at 01:06 AM

Okaaay, it goes something like this:

```
public void Vector2Limiter(Vector2 amount,Vector2 axis,float axisDegrees){
float axisFreedom=Mathf.Max(0f,1f-(Mathf.Min(Vector2.Angle(axis,amount),Vector2.Angle(-axis,amount))/axisDegrees));
Vector2 axisAmount=axis*(Vector2.Dot(axis,amount)/axis.magnitude);
return axisAmount+(amount-axisAmount)*axisFreedom;
}
```

It takes a vector, an axis and a number of degrees we allow to deviate from the axis before vector turns to zero. This function allows moving to both directions on the axis but it's easy to change that.

So the idea is to create a new vector which is a projection of the amount on the axis and then subtract that projection from original amount to find the vector perpendicular to the axis and then multiply it by an axisFreedom number which is a representation of how far we deviated from the axis from 0 to 1.

That's exactly what I wanted. But maybe there's a more efficient way of doing it? I'm doing it every frame and it would help a lot if someone new a better way.

Looking at the way you originally put your question, (and the images) I'd propose something like this:

```
public Vector2 Vector2Limiter(Vector2 input, Vector2 target, float angle)
{
float difference = Vector2.Angle(input, target);
float multiplier = Mathf.Max(0, 1f - difference / angle);
return input * multiplier;
}
```

What this does is it changes the magnitude of input based on the difference in angle to target. Where

Magnitude is unchanged if difference is 0.

Magnitude is 0 when difference is >= angle.

But sinse this does something else then what you posted as your accepted answer, I'm guessing I'm not understanding your original question correctly... If I did understand it correctly though, and this is actually the behaviour you want, this solution is simpler and more efficient :p

You're right. It totally may be that I didn't knew what I wanted and achieved a slightly different thing. My code keeps a component that falls on the target and shrinks the perpendicular component. So it doesn't shrink the whole vector but only the component of it that is perpendicular to the target. So yeah, your answer is better. But my does what I really want. My question was not expressed well enough :) Thanks. I've tried your code to make sure if it's a behavior I want and I still want mine. And I still wonder if I can make what I've written more efficient.

**Answer** by troien
·
May 17, 2019 at 06:09 PM

Based on my previous comment to your answer and on how to make it more efficient.

The following code does something similar. In my code I use sqrMagnitude instead of magnitude. because it is way more efficient. It yields a slightly different result, but depending on what you want, I'm thinking the result of using sqrMagnitude is actually more accurate then using magnitude... Especially when target is not normalized (like a value of [10,10], which makes the magnitude of your result explode in a way I don't think you intended)

The only real difference in this code is that it doesn't 'suffer' (don't know whether it is intended or not) from the same problem that you have when pointing in the opposite direction of target, and if you change sqrmagnitude to magnitude, it will do everything else exactly the same as your current answer as far as I could test...

```
public Vector2 Vector2Limiter2(Vector2 input, Vector2 target, float angle)
{
// If we imagine input is a point is space and target is a line from [0,0] to target,
// then pointInLine is the closest point on that line to input
Vector2 pointOnLine = target * Vector2.Dot(input, target) / target.sqrMagnitude;
float difference = Vector2.Angle(input, target);
float t = Mathf.Max(0, 1f - difference / angle);
return Vector2.Lerp(pointOnLine, input, t);
}
```

So basically. Most of the stuff I'm doing is the same thing as what you are doing, sqrMagnitude is the only real difference in performance, and personally I think it is slightly more readable. But I might be biased :D

Thanks a lot! And you're totally right. I write unreadable code just to put everything in one line.

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

calculate velocity vector based on direction 1 Answer

How Vectors work and how I should use them? 1 Answer

When i add a new force to my planet it is much stronger on the y axis than the x axis 1 Answer

Switch force from horizontal to vertical 1 Answer

Increasing the speed of a ball in a brick breaker game 0 Answers