using UnityEditor;
using UnityEngine;
public class DrawSector : MonoBehaviour
{
//扇形角度
public float angle = 80f;
//扇形半径
public float radius = 3.5f;
//物体B
public Transform b;
private bool flag;
private void Update()
{
flag = IsInRange(angle, radius, transform, b);
}
/// <summary>
/// 判断target是否在扇形区域内
/// </summary>
/// <param name="sectorAngle">扇形角度</param>
/// <param name="sectorRadius">扇形半径</param>
/// <param name="attacker">攻击者的transform信息</param>
/// <param name="target">目标</param>
/// <returns>目标target在扇形区域内返回true 否则返回false</returns>
public bool IsInRange(float sectorAngle, float sectorRadius, Transform attacker, Transform target)
{
//攻击者位置指向目标位置的向量
Vector3 direction = target.position - attacker.position;
//点乘积结果
float dot = Vector3.Dot(direction.normalized, transform.forward);
//反余弦计算角度
float offsetAngle = Mathf.Acos(dot) * Mathf.Rad2Deg;
return offsetAngle < sectorAngle * .5f && direction.magnitude < sectorRadius;
}
private void OnDrawGizmos()
{
Handles.color = flag ? Color.red : Color.cyan;
float x = radius * Mathf.Sin(angle / 2f * Mathf.Deg2Rad);
float y = Mathf.Sqrt(Mathf.Pow(radius, 2f) - Mathf.Pow(x, 2f));
Vector3 a = new Vector3(transform.position.x - x, 0f, transform.position.z + y);
Vector3 b = new Vector3(transform.position.x + x, 0f, transform.position.z + y);
Handles.DrawLine(transform.position, a);
Handles.DrawLine(transform.position, b);
float half = angle / 2;
for (int i = 0; i < half; i++)
{
x = radius * Mathf.Sin((half - i) * Mathf.Deg2Rad);
y = Mathf.Sqrt(Mathf.Pow(radius, 2f) - Mathf.Pow(x, 2f));
a = new Vector3(transform.position.x - x, 0f, transform.position.z + y);
x = radius * Mathf.Sin((half - i - 1) * Mathf.Deg2Rad);
y = Mathf.Sqrt(Mathf.Pow(radius, 2f) - Mathf.Pow(x, 2f));
b = new Vector3(transform.position.x - x, 0f, transform.position.z + y);
Handles.DrawLine(a, b);
}
for (int i = 0; i < half; i++)
{
x = radius * Mathf.Sin((half - i) * Mathf.Deg2Rad);
y = Mathf.Sqrt(Mathf.Pow(radius, 2f) - Mathf.Pow(x, 2f));
a = new Vector3(transform.position.x + x, 0f, transform.position.z + y);
x = radius * Mathf.Sin((half - i - 1) * Mathf.Deg2Rad);
y = Mathf.Sqrt(Mathf.Pow(radius, 2f) - Mathf.Pow(x, 2f));
b = new Vector3(transform.position.x + x, 0f, transform.position.z + y);
Handles.DrawLine(a, b);
}
}
}
OnDrawGizmos()是c#自带重载的一个方法属于Editor类型可以不加以运行便能进行显示绘制图形,如上述的Gif动图的扇形图形。它就是通过此代码生成的而最开始的Handles里的Bool值的一个方法是改变颜色用的,如果检测范围内有敌人的话则边框变为红色,平时为默认浅蓝色模样,而这一现象需要运行Unity才能看到效果因为在上面的IsInRange()方法内是判断是否在这个扇形范围内的方法,需要挂在Update()里实时检测。因为这个Update()是继承MonoBehaviour需要运行才能看到效果,而我在上面定义的Transform b 则是敌人的预制体我这边定义的是死的方便更直观的看到效果。