ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Unity计算两向量夹角以判断相对位置

2021-10-26 12:05:23  阅读:1025  来源: 互联网

标签:playerTrans Log Unity targetTrans Debug 夹角 向量 name


项目场景:

在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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有