Unity 角度与旋转(四元数与欧拉角)

在Unity中,角度与旋转是一个比较复杂的事情,其实现方式也是有很多,但是使用的规则是比较复杂的,所以需要选择对应的方式来实现需要的效果

一、Unity角度的表示方式

在Unity中表示角度的方式主要有两种,四元数与欧拉角,两者的表示方式有很大的不同,需要深刻理解两者,才能更好的应用:

四元数(Quaternion):

  • 四元数可用于表示GameObject的方向或旋转。该表示法内部包含四个数字(在Unity中称为x,y,z和w),但是这些数字并不表示角度或轴,因此通常不需要直接访问它们。除非您对四元数的数学特别感兴趣,否则您只真正需要知道四元数表示3D空间中的旋转,并且通常不需要知道或修改x,y和z属性

欧拉角(EulerAngles):

  • 欧拉角相对于四元数更加直观,可以直接看到旋转的角度,欧拉角的取值范围在0到360度,我们通常对于具体的角度的旋转使用欧拉加是简单方便的一种方式。

二、检查器(Inspector)面板Rotation

在我们创建一个3D物体时,Transfrom组件上就会有Rotation这个属性,Untiy官方手册解释为围绕X、Y或者Z轴进行的旋转,当我们在Sence面板对物体进行旋转,同样就会在Transform组件在看到数字的变化。反之,我们在面板调整数字,同样Sence窗口物体也会做出旋转。
在这里插入图片描述

但是当我们在脚本调用Rotation并输出,Debug输出发现与Tansform组件中显示的数字并不相同,而是一个四元数,并且每个数字都是从-1到1,这是为什么呢。其实Rotation并不是和检查面板显示的那样,Rotation是一个四元数,而其数值的正负值往往代表的是旋转方向,而其数值大小0到1则对应0到180度的对应:
在这里插入图片描述

所以说,与其说在Transform面板Rotation是一个四元数,不如将其理解为欧拉角,这样便于直观的使用角度。

三、持续旋转

Rotate

持续旋转是比较常用的旋转方式,不注重旋转角度,更注重旋转的速度,比如车轮旋转、摩天轮旋转等等,这样的可以使用transform.Rotate()来完成。而Rotate()就相当于获取一个旋转速度

使用方式:
public void Rotate(Vector3 eulers, Space relativeTo = Space.Self);

  • eulers:旋转角度的三维数

Rotate:

  • 使用Transform.Rotate以多种方式旋转GameObject。旋转通常以欧拉角而不是四元数提供
  • Rotate将Vector3参数作为欧拉角。第二个参数是旋转轴,可以将其设置为局部轴(Space.Self)或全局轴(Space.World)。旋转是欧拉量

具体使用方法的几种案例:

 	    //1,相对于世界坐标
        transform.Rotate(Vector3.left, Space.World);

        //2,相对于局部坐标,也就是自身坐标
        transform.Rotate(Vector3.forward, Space.Self);

        //3,基本用法
        float speed = 1f;
        Vector3 v3 = new Vector3(10, 10,10);
        transform.Rotate(v3*speed*Time.deltaTime);

四,角度转换到目标角度

eulerAngles:

Transform.eulerAngles表示世界空间中的旋转。在检查器中查看GameObject的旋转时,您可能会看到与此属性中存储的角度值不同的角度值。这是因为Inspector显示本地旋转,可以使用Transform.localEulerAngles来查看本地的角度显示。

关于Transform.eulerAngles

  • 最需要注意的一点是欧拉角的读取数值是介于0到360度的,所以无论读写,可能数值与Transform面板数值不同,同时,最重要的一点,由于这种特性,对其数值的累加可能出错

虽然累加可能出错,尽量不要尝试使用eulerAngles来实现旋转,但是也是可以通过累加来实现对于物体的旋转控制的,虽然累加之后并不是按照数值的递增,但是最终呈现的实物效果还是在旋转状态的:

private Vector3 v3;
    private void Start()
    {
    
    
       v3 = new Vector3(0, 0, 0);
    }
    // Update is called once per frame
    void Update()
    {
    
    
        v3 += new Vector3(0, 1, 0);
        transform.eulerAngles = v3;
        Debug.Log(transform.eulerAngles); 

测试结果为:
在这里插入图片描述
虽然其数值与Inspector面板不同,使用起来也比较麻烦,但是相对起来它是求物体转换到固定角度的最佳方法了,只是转换时要对数值敏感,选择合适的数值才能起到好的效果。

Quaternion:

Unity提供了将欧拉角转换为四元数的方法,可以使用Quaternion.Lerp()方法来完成,这是一种插值旋转方法,所以旋转速度会越来越慢,适合模拟减速效果:


transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, 90), 0.05f);

Quaternion方法:

  • Quaternion.RotateTowards():插值旋转至与目标角度相同
  • Quaternion.LookRotation():插值旋转看向目标

可以通过上面两种方法完成看向目标,或与目标角度一致,具体用法可以为:

        //与target保持一样的角度
        transform.rotation = Quaternion.RotateTowards(transform.rotation,target.rotation,2f);
        //看向目标
        transform.rotation = Quaternion.LookRotation(target.position);

五、总结

关于角度是Unity中比较难理解的知识,需要对于几种方法有所区分,并选择合适的来应用,虽然有些功能另外的方法也可以使用,但是用起来会很复杂且难以扩展,有一定局限,所以应用前应该做好选择

猜你喜欢

转载自blog.csdn.net/xinzhilinger/article/details/111469849