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.
[148525-arcbug.png*_|148525]
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_.x, position.y, position.z + arcPoints*.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);
}
}
}
}
_*