【Unity 24】Unity中的向量点乘和叉乘的应用

PS:本系列笔记将会记录我此次在北京学习Unity开发的总体过程,方便后期写总结,笔记为日更。
笔记内容均为 自己理解,不保证每个都对

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

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:设置矩形体区域

    /// 
    /// 以攻击点为中心,长为 2 * distance 宽为 2 * half 高为2 * height的矩形体范围
    /// 
    /// 生成范围的中心点的位置
    /// 目标物体的位置
    /// 中心点到两侧的宽度,实际宽度为2倍长度
    /// 中心点到最远攻击点的距离
    /// 中心点到最高的距离
    /// 
    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:设置扇形体区域


    /// 
    /// 以攻击点为中心,到任一点夹角为45°,且长度为radius的扇形体区域
    /// 扇形所指的为 以攻击点为固定点,长度为radius,角度为 2 * angle的覆盖区域
    /// 
    /// 攻击者的位置
    /// 被攻击者的位置
    /// 攻击点到其中一侧的夹角,即整个扇形角度为 2 * angle
    /// 
    /// 
    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°即为叉乘结果
【Unity 24】Unity中的向量点乘和叉乘的应用_第1张图片
叉乘简单应用:判断方向

    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);
    }

【Unity 24】Unity中的向量点乘和叉乘的应用_第2张图片
测试结果:
【Unity 24】Unity中的向量点乘和叉乘的应用_第3张图片

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().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);
        }
    }
}

根据以前内容,结合今天所学的点乘叉乘,可制作简易坦克大战Demo
【Unity 24】Unity中的向量点乘和叉乘的应用_第4张图片

你可能感兴趣的:(Unity,Unity,游戏开发,笔记)