点积
a·b= |a| *|b| * cos<a,b> => a·b= |1|
从上面的cos函数图可以得知,根据角色的视野正方向和角色到怪物的方向,两者夹角结果可以反推两个向量之间的夹角情况。
结果0,表示两个向量互相垂直
小于0,表示向量夹角大于90度
大于0,表示向量夹角小于90度。
a、根据夹角情况判断是否在视野范围内。比如知道角色的位置,也知道了怪物的位置,求怪物是否在角色的视角范围。通常情况下,人物角色的视野会设置为90度,和实际世界中人的视角范围124度比较是稍微小一点的。这里只考虑视野夹角,不考虑视野范围情况。
b、几何意义可以是求b在 a的投影。根据这个启发,dot值来判断怪物在前方还是后方。值为正时,目标在自己的前方,反之在自己的后方。
float dot = Vector3.Dot(direction, player.transform.forward);
Debug.Log("dot :" + dot);
if (dot >= 0)
{
Debug.Log("怪物在前方");
}
else
{
Debug.Log("怪物在后方");
}
c、漫反射dot(n,l),法线和光照的反方向点击,表示光在物体表面的漫反射情况。
叉积
实际是求两个向量(角色的正前方,从原点到怪物的位置)的法向量,法向量就是同时垂直与原来两个向量的新向量。要符合左手定则,中指是角色正方向,拇指是怪物方向,中指是法向量。
点积和叉积的用途实践。
求前后方向,求左右关系。
public bool IsInView(GameObject player, GameObject monster)
{
float distance = Vector3.Distance(player.transform.position, monster.transform.position);
if (distance > distanceThreshold)
{
Debug.Log("超出距离 distance :" + distance);
return false;
}
Vector3 direction = monster.transform.position - player.transform.position;
//计算两个向量的夹角
float angle = Vector3.Angle(direction, player.transform.forward);
Debug.Log("angle :" + angle);
//实际就是两个向量的模长乘以对应的cos(夹角),得到一个标量值。
float dot = Vector3.Dot(direction, player.transform.forward);
Debug.Log("dot :" + dot);
//由数学函数分布可以得知,0`90区间和270`360区间值都是整数的。
if (dot >= 0)
{
Debug.Log("怪物在前方");
}
else
{
Debug.Log("怪物在后方");
}
//实际是求两个向量(角色的正前方,从原点到怪物的位置)的法向量,法向量就是同时垂直与原来两个向量的新向量。要符合左手定则,中指是角色正方向,拇指是怪物方向,中指是法向量。
Vector3 cross = Vector3.Cross(player.transform.forward, monster.transform.position - Vector3.zero);
Debug.DrawLine(player.transform.position, Vector3.Cross(player.transform.forward, monster.transform.position - Vector3.zero));
//看看这条法向量是向下的还是向上的
Debug.Log("cross.y :" + cross.y);
if (cross.y >= 0)
{
Debug.Log("怪物在右方");
}
else
{
Debug.Log("怪物在左方");
}
return angle <= viewAngle;
}