功能说明:
根据怪物头和脚的位置,检测怪物整个身子(某部分也可以)是否在椎体视野范围内(不使用Collider碰撞)
思路:
符合一下2点之一的目标在椎体区域内
1. 目标头/脚的向量与自身方向夹角在椎体角度内 并且 目标头/脚距离在设定距离内
2.目标头与脚的线与平面相交
如果考虑墙的阻挡 可以附加射线检测
限制:
①视野平行,角色直立
②不考虑role的肥瘦
实验截图:
源码:
public class ConeSightTest : MonoBehaviour {
public GameObject srcPos;
public GameObject endPos;
public GameObject buttonPos;
public float Dic;
public float angle;
public Transform[] pHead;
public Transform[] pFoot;
private void Start()
{
angle = Vector3.Angle(srcPos.transform.forward, endPos.transform.position - srcPos.transform.position);
Dic = Vector3.Distance(srcPos.transform.position, endPos.transform.position);
}
void Update ()
{
for(int i=0;i<pHead.Length;i++)
{
if (IsTargetBodyInSectorRange(srcPos.transform.position, srcPos.transform.forward,
angle, Dic, pHead[i].position, pFoot[i].position))
{
Debug.DrawLine(pHead[i].position, pFoot[i].position,Color.red);
}
else
Debug.DrawLine(pHead[i].position, pFoot[i].position, Color.green);
}
}
public static bool IsTargetInSectorRange(Vector3 srcPos, Vector3 srcDir, float srcAngle, float srcDist,
Vector3 tarPos)
{
Vector3 toTarVec = tarPos - srcPos;
float deltaAngle = Vector3.Angle(srcDir, toTarVec);
if (deltaAngle < srcAngle)
{
float dist = Vector3.Distance(srcPos, tarPos);
if (dist < srcDist)
{
return true;
}
}
return false;
}
public static bool IsTargetBodyInSectorRange(Vector3 srcPos, Vector3 srcDir, float srcAngle, float srcDist,
Vector3 tarHeadPos, Vector3 tarFootPos)
{
if (IsTargetInSectorRange(srcPos, srcDir, srcAngle, srcDist, tarHeadPos))
return true;
if (IsTargetInSectorRange(srcPos, srcDir, srcAngle, srcDist, tarFootPos))
return true;
if (tarFootPos.y <= srcPos.y && srcPos.y <= tarHeadPos.y &&
IsTargetInSectorRange(srcPos, srcDir, srcAngle, srcDist, new Vector3(tarFootPos.x, srcPos.y, tarFootPos.z)))
return true;
return false;
}
}