Unity对象up轴指向目的方向进行旋转

今天想搞个人物旋转,但是需求比较特殊,坐标轴整体旋转了90度(ARToolKit的神奇设定),如果正常情况下最简单的做法就是LookAt方法或者Quaternion.FromtoRotation方法就可以直接搞定了,然而坐标旋转90度之后,相当于up方向为人物的面朝方向,所以直接用这两个方法就不行了,这两个方法都是默认的让物体的forward轴指向目标物体,所以要自己实现一套LookAt方法,使物体旋转,z轴指向目的物体。
自己实践了很久,一直有问题,于是在网上查了查,大部分都是说LookAt以及Quaterntion.FromtoRotation及其变种的,然而并没有解决问题,最后找到了这篇文章:

http://www.cnblogs.com/U-tansuo/archive/2012/07/11/2587179.html

这篇文章通过一个比较麻烦的方法,实现了点击屏幕,人物朝向点击地点,但是这正是我想要的,先贴上一下原文的代码:

void Update () 
{
       if(Input.GetMouseButtonDown(0))
       {
                RayControl();
       }
       if(flagMove)
       {
              if(Vector3.Distance(transform.position,mousePos)>1)
              {
                        transform.Translate(transform.worldToLocalMatrix* transform.forward * Time.deltaTime*5);//transform.forward是世界坐标,通过transform.worldToLocalMatrix转换矩阵转到本地坐标然后在本地坐标运动,没有必要必须在本地坐标系运动 但是必须注意要统一起来。
              }
              else
              {
                      flagMove=false;
              }
      }
}
void RayControl()
{
      Ray ray=Camera.main.ScreenPointToRay  (Input.mousePosition);//向屏幕发射一条射线
      if(Physics.Raycast(ray,out hit,200))射线长度为200 和地面的碰撞盒做检测
      {
               GameObject targetPos=GameObject.CreatePrimitive(PrimitiveType.Sphere);//实例化一个Sphere
               targetPos.transform.localScale=new Vector3(0.5f,0.5f,0.5f);
               mousePos=hit.point;//获取碰撞点坐标
               mousePos.y=transform.position.y;
               targetPos.transform.position=mousePos;//Sphere放到鼠标点击的地方
               targetDir=mousePos-transform.position;//计算出朝向
               Vector3 tempDir=Vector3.Cross(transform.forward,targetDir.normalized);//用叉乘判断两个向量是否同方向
               float dotValue=Vector3.Dot(transform.forward,targetDir.normalized);//点乘计算两个向量的夹角,及角色和目标点的夹角
               float angle=Mathf.Acos(dotValue)*Mathf.Rad2Deg;
               if(tempDir.y<0)//这块 说明两个向量方向相反,这个判断用来确定假如两个之间夹角30度 到底是顺时 还是逆时针旋转。
               {
                   angle=angle*(-1);
               }
               print(tempDir.y);
               print("2:"+angle);
               transform.RotateAround(transform.position,Vector3.up,angle);
               flagMove=true;
        }
}


然后就是我的问题了,让对象的up方向指向目的地点:

 	//获得方向
        Vector3 dir = transform.position - target.transform.position;
        //z的值保持不变,只在xy方向上进行旋转
        dir.z = CurrentObject.transform.position.z;
        //点乘计算两个向量的夹角,及角色和目标点的夹角(本人的项目中-up轴是正方向)
        float dotValue = Vector3.Dot(-CurrentObject.transform.up, dir.normalized);
        //获得夹角值
        float angle = Mathf.Acos(dotValue) * Mathf.Rad2Deg;
        //用叉乘判断两个向量是否同方向
        Vector3 tempDir = Vector3.Cross(-CurrentObject.transform.up, dir.normalized);
        if (tempDir.z < 0)//说明两个向量方向相反,这个判断用来确定假如两个之间夹角30度 到底是顺时 还是逆时针旋转。
        {
            angle = angle * (-1);
        }
        transform.RotateAround(CurrentObject.transform.position, Vector3.forward, angle);


终于解决了这个困扰我两天的问题了....



你可能感兴趣的:(Unity3d)