Unity计算两向量夹角以判断相对位置
作者:互联网
项目场景:
在Unity中,通过计算两个向量之间的夹角判断两者之间的相对位置
因为玩家在进行旋转看向目标时,需要按需播放“左转”或“右转”动画,所以需要先判定目标与玩家的相对位置。
解决方案:
首先需要了解关于两个向量“点积”的知识。然后你才能理解求弧度的过程!
这里有个链接,我认为能很好帮你理解这一点。向量内积与外积
接下来就是解决思路了,首先创建一个脚本CaculateAngle.cs,定义两个Transform分别保存玩家与目标的位置信息,暂且面名为playerTrans(玩家)和targetTrans(目标)。
获取需要计算的方向向量
因为我们默认玩家的正前方为起始朝向,而玩家到目标的方向,则是我们需要进行判定的方向。所以这里我们可以得到两个向量。我们暂且把他们命名为ori(起始向量)和dir(目标向量)。
效果展示:
蓝色的是Cube,红色的Cube2
源码:
public class CaculateAngle : MonoBehaviour
{
public Transform playerTrans;//玩家transform信息
public Transform targetTrans;//目标transform信息
private void Start()
{
if (playerTrans == null)//如果不进行赋值则默认此脚本挂在物体为玩家
{
playerTrans = transform;
}
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.C))//按下“C”进行计算
{
计算朝向(playerTrans.position, targetTrans.position);
}
}
public 方向 计算朝向(Vector3 起点, Vector3 终点)
{
起点 = playerTrans.position;
终点 = targetTrans.position;
起点.y = 0;//这里是只在一个平面上考虑,不需要可把这两个y的赋值删除。但下面进行位置判定就需要多几步了
终点.y = 0;
Vector3 dir = 终点 - 起点;
var f = Vector3.Dot(playerTrans.forward, dir);//求点积
Debug.Log("点积:" + f);
var a = Vector3.Magnitude(playerTrans.forward);//计算两个向量的“模”,如果不清楚“模”的概念可以先去了解一下“向量的模”
var b = Vector3.Magnitude(dir);
Debug.Log("两个向量的模:" + a + ":" + b);
f = (f / (a * b));//计算两个向量夹角的余弦值
Debug.Log("余弦值:" + f);
var h = Mathf.Acos(f);//通过Acos函数可通过余弦值计算出对应弧度
Debug.Log("弧度:" + h);
var d = (h *= Mathf.Rad2Deg);//弧度转度。这里得到的始终为正值
float x = dir.x;//因为我计算的平面是在xz上,所以x的值的正负可以判定在左(小于0)还是在有(大于0)
//但只通过X的值是没法判定正前方和正后方的。所以还需要借助余弦的值进行判定。起始两向量的点积也能进行位置的判断,这里就不过多讨论了,感兴趣的小伙伴可以去试试。
if (x > 0)
{
Debug.Log("<color=red>" + targetTrans.name + "</color>在" + playerTrans.name + "<color=red>" + 方向.右边 + "</color>");
Debug.Log("度:" + d);
return 方向.右边;
}
else if (x < 0)
{
Debug.Log("<color=red>" + targetTrans.name + "</color>在" + playerTrans.name + "<color=red>" + 方向.左边 + "</color>");
d *= -1;//由于计算的度数值始终为正,我们再次做一下处理,将左边默认为负的度数。
Debug.Log("度:" + d);
return 方向.左边;
}
else
{
if (f == -1)
{
Debug.Log("<color=red>" + targetTrans.name + "</color>在" + playerTrans.name + "<color=red>" + 方向.正后 + "</color>");
Debug.Log("度:" + d);
return 方向.正后;
}
else if (f == 1)
{
Debug.Log("<color=red>" + targetTrans.name + "</color>在" + playerTrans.name + "<color=red>" + 方向.正前 + "</color>");
Debug.Log("度:" + d);
return 方向.正前;
}
else
{
//因为可能会发生不可预料的错误(比如玩家和目标重合的极端情况),所以我们在此添加一个处理。
Debug.Log("<color=red>" + targetTrans.name + "</color>在" + playerTrans.name + "<color=red>" + 方向.方向错误 + "</color>");
Debug.Log("度:" + d);
return 方向.方向错误;
}
}
}
}
public enum 方向
{
方向错误,
左边,
右边,
正前,
正后
}
源工程下载
链接:https://pan.baidu.com/s/1wwtHPp8QT6Y2b-4lsSZgdA
提取码:79an
如果对你有帮助不要忘记点赞+收藏!谢谢!
注明:若有错误,请指正!
标签:playerTrans,Log,Unity,targetTrans,Debug,夹角,向量,name 来源: https://blog.csdn.net/weixin_44870508/article/details/120968117