向量的应用

点乘求角度,叉乘求方向

比如敌人再附近,点乘可以求出玩家面朝方向和敌人方向的夹角,叉乘可以得出左转还是右转更好的转向敌人

Part 1 点乘:

数学上的 点乘为 a * b = |a| * |b| * cos(Θ)

Unity中的点乘也是如此 点乘结果为 float 是投影长度

点乘的主要作用就是,点乘求角度。 Θ = Arcos( a * b / |a| * |b|)

代码实现:

        float tmpNormalized = Vector3.Dot(attacked.right.normalized, tmpDistance.normalized);      //计算出在攻击方向的单位向量上的投影

        float tmpRadian = Mathf.Acos(tmpNormalized);    //计算出弧度

        float tmpAngle = Mathf.Rad2Deg * tmpRadian; //弧度转换为角度


点乘的方法是

Vector3.Dot(向量A,向量B);   得到的结果是数  即 B在A上的投影长度

例如:

tmpDistanceX = Vector3.Dot(attacker.right, tmpDis); //即tmpDis 在 attacker.right向量上的投影长度

点乘的简单应用A:设置矩形体区域

    /// <summary>

/// 以攻击点为中心,长为 2 * distance 宽为 2 * half 高为2 * height的矩形体范围

    /// </summary>

    /// <param name="attacker">生成范围的中心点的位置</param>

    /// <param name="attacked">目标物体的位置</param>

    /// <param name="half">中心点到两侧的宽度,实际宽度为2倍长度</param>

    /// <param name="distance">中心点到最远攻击点的距离</param>

    /// <param name="height">中心点到最高的距离</param>

    /// <returns></returns>

    private bool RectAttack(Transform attacker, Transform attacked, float half, float distance, float height)    //生成一个矩形体范围的碰撞区域

    {

        Vector3 tmpDis = attacked.position - attacker.position;    //算出攻击者和被攻击者之间的向量差

        float tmpDistanceX, tmpDistanceY, tmpDistanceZ;

        tmpDistanceX = Vector3.Dot(attacker.right, tmpDis);        //算出向量差在 攻击方向上的投影,设攻击方向为  right

        Debug.Log("tmpDistance.X = " + tmpDistanceX);

        //float tmpDistance = Vector3.Distance(attacker.position, attacked.position);      //实际距离

        //Debug.Log("tmpDistance = " + tmpDistance);         

        if (tmpDistanceX >= 0 && tmpDistanceX <= distance)    //判断投影是在 攻击方向正面,且在攻击范围内

            //排除了目标在攻击点背后的情况

        {

            tmpDistanceZ = Mathf.Abs(Vector3.Dot(attacker.forward, tmpDis));              //计算向量差在 攻击范围横轴上的距离

            tmpDistanceY = Mathf.Abs(Vector3.Dot(attacker.up, tmpDis));            //计算向量差在 攻击范围横轴上的距离

            if (tmpDistanceZ <= half && tmpDistanceY <= height)            //在范围内则进行攻击

            {

                Debug.Log("Attacked!!!");

                      return true;

            }

        }

        return true;

    }

点乘的简单应用B:设置扇形体区域

    /// <summary>

    /// 以攻击点为中心,到任一点夹角为45°,且长度为radius的扇形体区域

    /// 扇形所指的为 以攻击点为固定点,长度为radius,角度为 2 * angle的覆盖区域

    /// </summary>

    /// <param name="attacker">攻击者的位置</param>

    /// <param name="attacked">被攻击者的位置</param>

    /// <param name="angle">攻击点到其中一侧的夹角,即整个扇形角度为 2 * angle</param>

    /// <param name="radius"></param>

    /// <returns></returns>

    private bool UmbrallaAttack(Transform attacker, Transform attacked, float angle, float radius)      //生成一个扇形体范围的碰撞区域

    {

        Vector3 tmpDistance = attacked.position - attacker.position;        //算出攻击者和被攻击者之间的向量差

        //取值范围 [-1, 1]

        float tmpNormalized = Vector3.Dot(attacked.right.normalized, tmpDistance.normalized);      //计算出在攻击方向的单位向量上的投影

        float tmpRadian = Mathf.Acos(tmpNormalized);    //计算出弧度

        float tmpAngle = Mathf.Rad2Deg * tmpRadian;

        float tmpDis = tmpDistance.magnitude;          //已知向量,求tmpDistance的距离长度

        //float tmpDis2 = Vector3.Distance(attacker.position, attacked.position);    //求两点间的距离长度

        //Debug.Log("tmpAngle == " + tmpAngle + "tmpDis == " + tmpDis + "tmpDis2 == " + tmpDis2);

        if(tmpAngle <= angle && tmpDis <= radius)

        {

            Debug.Log("Attack!!!");

            return true;

        }

        return false;

    }


Part 2 叉乘:

数学上的叉乘 使用右手定则 确认 结果向量方向

Unity中的叉乘 使用左手定则 确认结果向量方向

叉乘方法

Vector3.Cross(tmpA, tmpB) 叉乘结果是一个向量

**叉乘的主要应用是:**求方向

在同一平面内, 结果 > 0 表示 B在A的逆时针方向, 结果 <0 表示B在A的顺式针方向, 结果 = 0表示B与A同向

左手定则:

Vector3.Cross(tmpA, tmpB) tmpA为大拇指,食指为tmpB, 其余三指自然弯曲90°即为叉乘结果

叉乘简单应用:判断方向

    private void CrossTest(Vector3 tmpA, Vector3 tmpB)

    {

        Vector3 result = Vector3.Cross(tmpA, tmpB);

        if(result.y> 0){

            Debug.Log("tmpB在tmpA的顺时针方向");

        }

        if (result.y == 0){

            Debug.Log("tmpB在tmpA同向");

        }

        if (result.y < 0)   {

            Debug.Log("tmpB在tmpA的逆时针方向");

        }

    }

    void Update()    {

        Vector3 tmpA = attacked.position - transform.position;

        Vector3 tmpB = newAttacked.position - transform.position;

        CrossTest(tmpB, tmpA);

    }


测试结果:

Part 3 点乘和叉乘的综合应用:

点乘求出相差角度,叉乘求出转向

让AI朝玩家方向自动移动,转向

    void Update()

    {

        Vector3 tmpVector = Player.transform.position - transform.position;

        float tmpDistance = tmpVector.magnitude;        //计算AI到Player之间的距离

        //Debug.Log("Distance == " + tmpDistance);

        if (tmpDistance <= 7)

        {

            TimeCount += 0.1f;

            if (TimeCount >= 0)

            {

                Debug.Log("Attack!!!");

                BulletParent.GetComponent<BulletGen>().GenBullet();    //调用子弹实例化脚本方法

                TimeCount = 0;

            }

            //transform.LookAt(Player);

        }

        else

        {

            Vector3 tmpCross = Vector3.Cross(transform.forward, tmpVector);    //叉乘计算书 玩家在AI的哪一侧

            if(tmpCross.y >= 0)

            {

                transform.Rotate(Vector3.up, 0.5f);

            }

            if (tmpCross.y < 0)

            {

                transform.Rotate(Vector3.up, -0.5f);

            }

            transform.Translate(Vector3.forward* 0.02f, Space.Self);

        }

    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容