向量

大小

向量的模长
公式:Mathf.Sqrt(Mathf.Pow(T1.pos.x,2),Mathf.Pow(T1.pos.y,2),Mathf.Pow(T1.pos.z,2));
Api: T1.pos.magnitude;

方向

公式: V/|V|, 向量除于其模长,
T1.pos / Mathf.Sqrt(Mathf.Pow(T1.pos.x,2),Mathf.Pow(T1.pos.y,2),Mathf.Pow(T1.pos.z,2));
结果:一个向量除于一个float,得到的结果还是一个向量
Unity Api: T1.pos.normalized;

点乘

点乘结果与角度之间的关系

unity向量转换 unity向量旋转角度_unity向量转换

欧拉角

  • 使用三个角度来保存方位
  • X 与 Z 沿自身坐标系旋转,Y 轴沿世界坐标系旋转。
  • API: Vector3 eulerAngle = transform.eulerAngles;

四元素

公式:
//旋转轴
Vecter3 axis = Vecter3.up;//或者:tar.position-irg.position;
//旋转角度
float angle = 50;
//角度转弧度:

float rad = Mathf.Deg2Rad(angle);
Quaternion qt = new Quaternion();
qt.x = Mathf.Sin(rad/2)* axis.x;
qt.y = Mathf.Sin(rad/2)* axis.y;
qt.z=Mathf.Sin(rad/2)* axis.z;
qt.w=Mathf.Cos(rad/2);
this. transform. rotation = qt;

欧拉角转四元素API:
this. transform. rotation = Quaternion. Euler(0,50,0);

四元素转欧拉角API
Quaternion qt = transform. rotation;
Vector3 euler = qt.eulerAngles;

轴/角旋转:
Quaternion qt = Quaternion.AngleAxis(50, Vector3.up);//沿y轴旋转50度,这个轴可以是任意轴,两向量相减得到的方向也可。

注视旋转:

当前物体的z轴注视某个方向并沿其旋转
 if(GuiLayout.Button(""){
 Quaternion dir = Quaternion. LookRotation(tf.position - transform. position);
 //差值旋转
 Quaternion.Lerp ( transform. rotation,dir,0.1f);
 }//从当前的z轴看向的方向慢慢转向dir所表示的方向。
 //匀速旋转
 Quaternion.RotateToWards ( transform. rotation,qt ,0.1f);//通过判断两个四元素之间的角度来确定两个四元素是否足够接近
 float angel = Quaternion. Angle( transform. rotation,qt );//指定物体的轴旋转到某方向
 transform. rotation = Quaternion. FromToRotation ( Vector3. right, dt.position - transform. position);//
 四元素相乘
 两个四元素相乘达到组合旋转的效果
 this. transform. rotation *= Quaternion.Euler(20,0,0);
 //将一个物体沿自身的x轴旋转20度
 四元素组合使用 *=
 向量组合使用 +=
 Quaternion qt = new Quaternion();
 qt = Quarternion.Euler(0,20,0) * Quaternion.Euler(20,60,0);
 等价于:qt = Quaternion.Euler(20,80,0);

Unity中访问四元素与欧拉角的api
四元素: transform. rotation ;
欧拉角: transform.eulerAngle;

四元素与欧拉角灵活使用以达到好用的同时又能避免万向节死锁
限制角度时使用欧拉角,无角度限制时使用四元素!

四元素与向量相乘,表示将该向量沿着四元素表示的角度旋转。例如:
Vector3 vet1 = Vector3. forward*10;
//世界坐标正前方十米
//将它沿着y轴旋转30度
Vector3 vet2 = Quaternion.Euler(0,30) * ver1;
//这个vet2就是旋转30度后该向量所在的位置

叉乘,结合点乘可知该物体所在的方向是在左边还是右边

#region  叉乘
    ///<summary>
    ///叉乘
    ///垂直与这两个向量构成的平面的向量
    ///</summary>    
    void Demo6(){
        //点乘
        float T1DotT2 = Vector3.Dot(T1.transform.position.normalized,T2.transform.position.normalized);
        //叉乘
        Vector3 T1CrossT2 = Vector3.Cross(T2.transform.position.normalized,T1.transform.position.normalized);
        Debug.LogFormat("T1 叉乘 T2 = {0}",T1CrossT2);
        //Mathf.Acos 弧度,需要转换成角度 Mathf.Rad2Deg
        float angle = Mathf.Acos(T1DotT2) * Mathf.Rad2Deg;
        if(T1CrossT2.y < 0){
            angle = 360 - angle;
        }
        Debug.LogFormat("T1 与 T2 的夹角为:{0}",angle);
        Debug.DrawLine(Vector3.zero,T1.transform.position,Color.red);
        Debug.DrawLine(Vector3.zero,T2.transform.position,Color.green);
        Debug.DrawLine(Vector3.zero,T1CrossT2.normalized * 5,Color.blue);
    }
    #endregion

计算切点

public Transform T2;
    private string PlayTag = "Player";
    private float PlayerRadio;
    GameObject Player;
    // Start is called before the first frame update
    void Start()
    {
        Player = GameObject.FindGameObjectWithTag(PlayTag);
        CharacterController cctro = Player.GetComponent<CharacterController>();
        if (cctro!= null) PlayerRadio = cctro.radius;
    }
    void Update()
    {
      CalculateTangent();
        Debug.DrawLine(T2.transform.position,leftTangent);
        Debug.DrawLine(T2.transform.position,rightTangent);
	}
	#region  切点
    ///<summary>
    ///切点
    ///</summary>    
    private Vector3 leftTangent,rightTangent;
    void CalculateTangent(){
       Vector3 playerToExplosion = T2.transform.position - Player.transform.position;
       Vector3 PlayerToExplosionDirection = playerToExplosion.normalized;
       float angle = Mathf.Acos(PlayerRadio/playerToExplosion.magnitude) * Mathf.Rad2Deg;   
       leftTangent = Player.transform.position + Quaternion.Euler(0,-angle,0) *(PlayerToExplosionDirection * PlayerRadio);  
       rightTangent = Player.transform.position + Quaternion.Euler(0,angle,0) *(PlayerToExplosionDirection * PlayerRadio);  
    }
    #endregion

unity向量转换 unity向量旋转角度_叉乘_02


画箭头

void Demo7(){
        //画箭身
        Vector3 arrow = T2.transform.position - T1.transform.position;
        float arrowLength = arrow.magnitude;    //箭身长度        

        //箭方向的反方向
        Vector3 arrowHead = arrow.normalized * -1;
        //箭头的长度
        Vector3 arrowHeadLength = arrowHead * Mathf.Clamp((arrowLength/10),0.3f,0.68f);
        //向左旋转
        Vector3 leftArrowHead  = T2.transform.position  + Quaternion.Euler(0,15,0) * arrowHeadLength;
        //向右旋转
        Vector3 rightArrowHead  = T2.transform.position + Quaternion.Euler(0,-15,0) * arrowHeadLength;
       //箭头封口处
        Vector3 arrowHead2 = T2.transform.position  + arrowHead * Mathf.Sin(30*Mathf.Deg2Rad) * (leftArrowHead -T2.transform.position).magnitude;
        
        Debug.DrawLine(T1.transform.position,T2.transform.position,Color.red);
        Debug.DrawLine(T2.transform.position,leftArrowHead,Color.red);
        Debug.DrawLine(T2.transform.position,rightArrowHead,Color.red);
        Debug.DrawLine(leftArrowHead,arrowHead2,Color.red);
        Debug.DrawLine(rightArrowHead,arrowHead2,Color.red);
    }
    #endregion

unity向量转换 unity向量旋转角度_unity向量转换_03