内容纲要

nav.desiredVelocity:导航网格期望达到的(当前速度到期望速度有一个加速过程)的目标速度
求desiredVelocity的模作为作为速度方向,移动速度就是向量长度
ProjectOnPlane:计算一个向量在某一平面上的投影
确定平面点法式,三点式
角度用四元数表示
FromToRotation

Turn计算旋转角度

计算旋转角度,鼠标寻路时播放旋转动画插图

 bool IsPathComplete()//判断寻路是否结束
    {
        return nav.pathPending == false && nav.remainingDistance <= nav.stoppingDistance;
    }
 //寻路中
                forward = nav.desiredVelocity.magnitude;//求模
                                                        //方法1
                                                        //设置forward和turn变量

                //计算desiredVelocity在x-z平面上的投影
                Vector3 desiredXZ = Vector3.ProjectOnPlane
                    (nav.desiredVelocity, Vector3.up);
                Debug.DrawRay(transform.position, desiredXZ.normalized * 10);//打印法线
                Vector3 forwardXZ = Vector3.ProjectOnPlane(transform.forward, Vector3.up);
                Debug.DrawRay(transform.position, forwardXZ.normalized * 10);
                ////旋转可以用四元数或欧拉角表示,但Unity内部统一使用四元数表示
                ////在3D引擎调用图形接口(D3D,OpenGL)进行硬件加速的图形变换时
                ////四元数会被转换成矩阵进行旋转
                Quaternion q = Quaternion.FromToRotation(forwardXZ, desiredXZ);
                turn = q.eulerAngles.y;//{0,360}=>{-180,180}/180=>{1,-1}
                if (turn > 180)
                {
                //    //181=>-179
                //    //359=>-1
                    turn = turn - 360;

                }
                    turn = turn / 180;

鼠标控制修改

对之前做了一定修改整合

 else
        {
        if (v < 0)//向后移动速度减慢
        {
            v *= 0.5f;  
        }
        forward = v * moveSpeed;//v={-1,1},moveSpeed=5 =>{-5,5}超出范围

        if (Input.GetMouseButton(1))
        {
            turn = mouseX * rotSpeed;
            //this.transform.Rotate(0,turn, 0, Space.Self);//局部坐标系移动
        }
        turn += h * rotSpeed;//{-360,360}/360={-1,1}=>{左半圈,右半圈}
           turn /= 360;
        }
        //h={-1,1},mousex={-1,1},rootspeed=180

        //执行
        //this.transform.Translate(0, 0, forward, Space.Self);
        //this.transform.Rotate(0,turn, 0, Space.Self);
        anim.SetFloat("Forward", forward/moveSpeed,0.5f,Time.deltaTime);//缓冲传导,更平滑
        anim.SetFloat("Turn",turn,0.2f,Time.deltaTime);//

第二种方法

用tan方法求角度,角色到世界旋转逆变换为世界到角色的反向旋转量,
对边除以领边得到tan,再用atan(z,x)得到旋转量。
计算旋转角度,鼠标寻路时播放旋转动画插图(1)

 //方法2
                //1.把角色到世界的旋转逆变换为世界到角色的反向旋转量

                Vector3 desiredLocal= Quaternion.Inverse(transform.rotation) * nav.desiredVelocity;
                //计算得到一个世界空间向量在player局部坐标空间中的向量
                //2.计算得到desiredLocal对应的旋转弧度
                turn = Mathf.Atan2(desiredLocal.x, desiredLocal.y);

发表评论