# How to detect when an object is within an arc?

I'm having an issue trying to detect an object within an arc. What I'm trying to do is, after setting a minimum and maximum angle, detect an object that falls within that range. When I put in angle values like -60 degrees to 60 degrees, it works fine. When I put in a value that's 180 degrees (-90 to 90), my calculated Forward vector gets set to 0 (because I'm calculating a vector between the 2 angles), and when it's greater than 180 degrees, the detection becomes flipped.

Below are examples.

**Red Lines** = Detection Arc.

**Green Line** = Forward Axis.

**Cyan Line** = Detected Target.

And here is the code:

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MountedTurret : MonoBehaviour
{
[System.Serializable]
public class Turret
{
[SerializeField]
Vector3 _localPosition;
[SerializeField]
float _angleMin = -90;
[SerializeField]
float _angleMax = 90;
public float Range = 10f;
public float AngleMin(Transform t)
{
return _angleMin + t.eulerAngles.y;
}
public float AngleMax(Transform t)
{
return _angleMax + t.eulerAngles.y;
}
public Vector3 Position(Transform t)
{
return t.position + _localPosition;
}
public Vector3 Forward(Transform t)
{
var position = Position(t);
float aMin = AngleMin(t);
float aMax = AngleMax(t);
Vector3 vMin = new Vector3(Mathf.Sin(aMin * Mathf.Deg2Rad), 0, Mathf.Cos(aMin * Mathf.Deg2Rad));
Vector3 vMax = new Vector3(Mathf.Sin(aMax * Mathf.Deg2Rad), 0, Mathf.Cos(aMax * Mathf.Deg2Rad));
return ((vMin + vMax) * 0.5f).normalized;
}
public bool IsInRange(Transform t, Vector3 point)
{
var position = Position(t);
float dist = Vector3.Distance(position, point);
if(dist <= Range)
{
var direction = point - position;
float angle = Vector3.Angle(Forward(t), direction);
if(angle >= AngleMin(t) && angle <= AngleMax(t))
{
return true;
}
}
return false;
}
}
public Ship ship;
public Turret[] turrets;
public Transform test;
public void OnDrawGizmos()
{
const int segments = 5;
List<Vector2> arcPoints = new List<Vector2>();
float angle;
float arcLength;
Vector3 position;
foreach (Turret t in turrets)
{
position = t.Position(transform);
Gizmos.color = Color.green;
Debug.Log("My Forward is: " + t.Forward(transform));
Gizmos.DrawRay(position, t.Forward(transform) * t.Range);
angle = t.AngleMin(transform);
arcLength = t.AngleMax(transform) - angle;
for (int i = 0; i <= segments; i++)
{
float x = Mathf.Sin(Mathf.Deg2Rad * angle) * t.Range;
float y = Mathf.Cos(Mathf.Deg2Rad * angle) * t.Range;
arcPoints.Add(new Vector2(x, y));
angle += (arcLength / segments);
}
//TODO Draw the arc
Gizmos.color = Color.red;
var arcPos = new Vector3(position.x + arcPoints[0].x, position.y, position.z + arcPoints[0].y);
var prevPos = arcPos;
Gizmos.DrawLine(position, arcPos);
//TODO For
for(int i = 0; i < arcPoints.Count; ++i)
{
arcPos = new Vector3(position.x + arcPoints[i].x, position.y, position.z + arcPoints[i].y);
Gizmos.DrawLine(prevPos, arcPos);
prevPos = arcPos;
}
arcPos = new Vector3(position.x + arcPoints[arcPoints.Count - 1].x, position.y, position.z + arcPoints[arcPoints.Count - 1].y);
Gizmos.DrawLine(position, arcPos);
}
}
// Update is called once per frame
void Update()
{
foreach (Turret t in turrets)
{
if(t.IsInRange(transform, test.position))
{
Debug.DrawLine(t.Position(transform), test.position, Color.cyan);
}
}
}
}
```

**Answer** by VRKeith
·
Nov 10, 2019 at 04:09 PM

Thanks to Captain_Pineapple, I was able to figure out the answer, by converting my 2 angles into 2 planes!

Here is the revised IsInRange function, as well as 2 Plane generation functions:

```
public Plane MinPlane(Transform t)
{
var position = Position(t);
float aMin = AngleMin(t);
Vector3 vMin = new Vector3(Mathf.Sin(aMin * Mathf.Deg2Rad), 0, Mathf.Cos(aMin * Mathf.Deg2Rad));
Vector3 normal = Vector3.Cross(vMin, Vector3.down);
return new Plane(normal, position);
}
public Plane MaxPlane(Transform t)
{
var position = Position(t);
float aMax = AngleMax(t);
Vector3 vMax = new Vector3(Mathf.Sin(aMax * Mathf.Deg2Rad), 0, Mathf.Cos(aMax * Mathf.Deg2Rad));
Vector3 normal = Vector3.Cross(vMax, Vector3.up);
return new Plane(normal, position);
}
public bool IsInRange(Transform t, Vector3 point)
{
var position = Position(t);
float dist = Vector3.Distance(position, point);
if(dist <= Range)
{
var minP = MinPlane(t);
var maxP = MaxPlane(t);
var direction = point - position;
if(Vector3.Dot(minP.normal, direction) > 0 || Vector3.Dot(maxP.normal, direction) > 0)
{
return true;
}
}
return false;
}
```

**Answer** by Captain_Pineapple
·
Nov 10, 2019 at 12:16 PM

Hey there,

take a look at this tutorial.

Do a projection as explained by the link and you geet a value that will indicate if your object is in the front or the back when the value "c" is positive/negative.

Let me know if that was too unclear and i can try to help you a bit more specifically.

It's a bit hard to follow, because, for some reason, the page isn't loading a script that looks up the math symbols, so everything looks like: [\begin{split}\L{ g \vec{v} }^2 = \\ ( g \vec{v} ) \cdot ( g \vec{v} ) = \\ g^2 \VL{v}^2 = 1\end{split}]

So, trying to follow here, we want to see if the object is in front or back via a dot product, but I'm not putting together where to do this. Should I make planes out of the angles and use that for the dot product?

### Your answer

### Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

### Follow this Question

### Related Questions

Get a Vector3 to always have a radius of 1 from 0, 0, 0 2 Answers

Vector Math - Linear Algebra 2 Answers

How to calculate next camera position to look at the object that changed rotation 1 Answer

How do I convert speed and heading to a vector? 3 Answers

Rotating a game object to match the surface of a 2D Line 0 Answers