向量
大小
即向量的模长
公式: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;
点乘
点乘结果与角度之间的关系
欧拉角
- 使用三个角度来保存方位
- 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
画箭头
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