Unity Quaternion

Quaternion 类的属性

eulerAngles  欧拉角

Quaternion 类的实例方法

1、SetFromToRotion 函数

2、SetLookRotation 函数

3、ToAngleAxis 函数

Quaternion 类的静态方法

1、Angle方法

2、Dot方法

3、Euler方法

4、FromToRotation方法

5、Inverse方法

6、Lerp方法

7、LookRotation方法

8、RotateToWards方法

9、Slerp方法

Quaternion 类的实例方法

SetFromToRotion 函数

1、public void SetFromToRotion(Vector3 fromDirection, Vector3 toDirection);

可以创建一个从向量fromDirection到向量toDirection的旋转。(fromDirection 和 toDirection 不能为Vector3.zero)

代码示例: m_q.eulerAngles = (45.0, 0.0, 0.0)

        // 向量1
        Vector3 v1 = new Vector3(2, 3, 4);
        Debug.DrawRay(Vector3.zero, v1.normalized * 3, Color.red);

        // 向量2
        Vector3 v2 = new Vector3(2, -3, -1);
        Debug.DrawRay(Vector3.zero, v2.normalized * 3, Color.green);

        // 四元数q1: 向量v1到向量v2的旋转
        Quaternion q1 = Quaternion.identity;
        q1.SetFromToRotation(v1, v2);

        // 设置cube0的旋转为q1
        m_cube0.rotation = q1;

        // 得到旋转后cube0坐标系中的变量v1,在世界坐标系中的向量v3
        Vector3 v3 = m_cube0.TransformDirection(v1);
        
        Debug.DrawRay(Vector3.zero, v3.normalized * 2, Color.blue);

由运行结果可以看到v3和v2指向相同,cube0做了如下变换,首先将自身坐标系与世界坐标系一致,然后将自身坐标系中v1指向的方向旋转到v2指向方向。

SetLookRotation 函数

1、public void SetLookRotation(Vector3 v1);

设置Quaternion实例的朝向与向量v1指向的方向相同

2、public void SetLookRotation(Vector3 v1, Vector3 v2);

设置transform.forward(z轴) 方向与v1方向相同,transform.right (x轴)垂直于由 Vector3.zer0、v1和v2这3点构成的平面。v2决定了transform.up(y轴)的朝向,因为当transform.forward和transform.right方向确定后,transform.up的方向总会与V2的方向的夹角小于或等于90度。当V1为Vector3.zero时,方法失效。

代码示例

    void Update()
    {
        Vector3 v1 = new Vector3(-3, 3, 3);
        Vector3 v2 = new Vector3(3, 4, 1);

        m_q.SetLookRotation(v1, v2);

        Debug.DrawLine(Vector3.zero, v1, Color.red);
        Debug.DrawLine(Vector3.zero, v2, Color.green);

        Debug.Log("m_cube0.forward = " + Vector3.Normalize(m_cube0.forward));
        Debug.Log("v1 = " + Vector3.Normalize(v1));


        Debug.Log("angle from m_cube0.right to v1 = " + Vector3.Angle(m_cube0.right, v1));
        Debug.Log("angle from m_cube0.right to v2 = " + Vector3.Angle(m_cube0.right, v2));

        Debug.Log("angle from m_cube0.up to v2 = " + Vector3.Angle(m_cube0.up, v2));

        m_cube0.rotation = m_q;
    }

ToAngleAxis 函数

1、public void ToAngleAxis(out float angle,out Vector3 axis);

参数angle为旋转角,参数axis为轴向量。

该函数可以实现将GameObject对象的rotation从Quaternion.identity状态变换到当前状态,只需要将GameObject对象绕着axis轴(世界坐标系)旋转angle角度即可。

代码示例

    public Transform m_cube0;
    public Transform m_cube1;
    public Transform m_cube2;

    public Vector3 m_axis;
    public float m_angle;

    public Vector3 m_eulerAngles;

    void Update()
    {
        m_eulerAngles.x += Time.deltaTime * 2.0f;
        m_eulerAngles.y += Time.deltaTime * 1.0f;
        m_eulerAngles.z += Time.deltaTime * 3.0f;

        m_cube0.eulerAngles = m_eulerAngles;

        m_cube0.rotation.ToAngleAxis(out m_angle, out m_axis);

        m_cube1.rotation = Quaternion.AngleAxis(m_angle, m_axis);

        Debug.DrawRay(m_cube1.position, m_cube1.forward * 2, Color.blue);
        Debug.DrawRay(m_cube1.position, m_cube1.right * 2, Color.red);
        Debug.DrawRay(m_cube1.position, m_cube1.up * 2, Color.green);
    }

 

Quaternion 类的静态方法

Angle 函数

1、public static float Angle(Quaternion a,Quaternion b);

该方法可以计算两个旋转状态a达到b时需要旋转的最小夹角。

代码示例

    private void Update()
    {
        // 向量1
        Vector3 v1 = new Vector3(2, 3, 4);

        Quaternion q1 = Quaternion.identity;
        Quaternion q2 = Quaternion.identity;
        q1.SetLookRotation(v1);

        float a1, a2;
        Vector3 v = Vector3.zero;

        a1 = Quaternion.Angle(q1, q2);

        q1.ToAngleAxis(out a2, out v);

        Debug.Log("a1: " + a1);
        Debug.Log("a2: " + a2 + "  v: " + v);

        Debug.Log("q1.eulerAngles: " + q1.eulerAngles + " q1: " + q1);
        Debug.Log("q2.eulerAngles: " + q2.eulerAngles + " q2: " + q2);


        Debug.DrawRay(Vector3.zero, v1.normalized * 5, Color.red);
        Debug.DrawRay(Vector3.zero, v.normalized * 5, Color.green);
    }

 

Dot 函数

1、public static float Dot(Quaternion a, Quaternion b);

该方法可以根据点乘的结果,判断a和b对应欧拉角的关系。

例如有两个Quaternion实例q1(x1,y1,z1,w1)和q2(x2,y2,z2,w2),则float f = Quaternion.Dot(q1,q2);即f = x1*x2+y1*y2+z1*z2+w1*w2,结果值f的范围为[-1,1]。当f=+(-)1时,q1和q2对应的欧拉角是相等的,即旋转状态是一致的。特别地,当f = -1时,说明其中一个rotation比另外一个rotation多旋转了360°。

        // 四元数q1, 四元数q2, 四元数q3, 四元数q4
        Quaternion q1 = Quaternion.Euler(10, 10, 10);
        Quaternion q2 = Quaternion.Euler(370, 370, 370);
        Quaternion q3 = Quaternion.Euler(10, 10, 10);
        Quaternion q4 = Quaternion.Euler(20, 40, 70);

        Debug.Log("Quaternion.Dot(q1, q2) = " + Quaternion.Dot(q1, q2));
        Debug.Log("Quaternion.Dot(q1, q3) = " + Quaternion.Dot(q1, q3));
        Debug.Log("Quaternion.Dot(q1, q4) = " + Quaternion.Dot(q1, q4));

Euler方法

1、public static Quaternion Euler(Vector3 euler);

2、public static Quaternion Euler(float x,float y,float z);

该方法用于返回欧拉角Vector3(ex,ey,ez)对应的四元数Quaternion q(qx,qy,qz,qw)。其对应关系如下:已知PIover180 = 3.141592/180 = 0.0174532925f是计算机图形学中的一个常亮,其变换过程如下:

        float PIover180 = 0.0174532925f;
        float ex = 30, ey = 40, ez = 50;

        Quaternion q = Quaternion.Euler(ex, ey, ez);
        Debug.Log("q.x = " + q.x);
        Debug.Log("q.y = " + q.y);
        Debug.Log("q.z = " + q.z);
        Debug.Log("q.w = " + q.w);


        ex = ex * PIover180 / 2.0f;
        ey = ey * PIover180 / 2.0f;
        ez = ez * PIover180 / 2.0f;

        float qx = Mathf.Sin(ex) * Mathf.Cos(ey) * Mathf.Cos(ez) + Mathf.Cos(ex) * Mathf.Sin(ey) * Mathf.Sin(ez);
        float qy = Mathf.Cos(ex) * Mathf.Sin(ey) * Mathf.Cos(ez) - Mathf.Sin(ex) * Mathf.Cos(ey) * Mathf.Sin(ez);
        float qz = Mathf.Cos(ex) * Mathf.Cos(ey) * Mathf.Sin(ez) - Mathf.Sin(ex) * Mathf.Sin(ey) * Mathf.Cos(ez);
        float qw = Mathf.Cos(ex) * Mathf.Cos(ey) * Mathf.Cos(ez) + Mathf.Sin(ex) * Mathf.Sin(ey) * Mathf.Sin(ez);

        Debug.Log("qx = " + qx);
        Debug.Log("qy = " + qy);
        Debug.Log("qz = " + qz);
        Debug.Log("qw = " + qw);

FromToRotation方法

1、public static Quaternion FromToRotation(Vector3 fromDirection,Vector3 ToDirection);

可以创建一个从向量fromDirection到向量toDirection的旋转。(fromDirection 和 toDirection 不能为Vector3.zero)。同SetFromToRotation实例方法的功能一样。

LookRotation方法

1、public static Quaternion LookRotation(Vector3 forward); public static Quaternion

2、LookRotation(Vector3 forward,Vector3 upwards);

参数forward为返回Quaternion实例的forward朝向。该方法和前面讲到的SetLookRotation实例方法的功能是一样。

Inverse方法

1、public static Quaternion Inverse(Quaternion rotation);

该方法可以返回参数rotation的逆向Quaternion值。例如rotation(x,y,z,w),那么Quaternion.Inverse(rotation) = (-x,-y,-z,w)。假设rotation的欧拉角为(a,b,c),则transform.rotation = Quaternion.Inverse(rotation)相当于transform依次绕自身坐标系的z轴、x轴和y轴分别旋转-c°、-a°和-z°。由于是在局部坐标系内的变换,最后transform的欧拉角的各个分量值并不一定等于-a、-b或-c。

Lerp方法 和 Slerp方法

1、public static Quaternion Lerp(Quaternion form, Quaternion to,float t);

2、public static Quaternion Slerp(Quaternion form, Quaternion to,float t);

两种方法的作用都是返回从form到to的插值。当参数t<=0时返回值为from,当参数t>=1时返回值为to。其中Lerp是线性差值,而Slerp是球面插值。

        Quaternion q1 = Quaternion.LookRotation(new Vector3(0, 0, 1));
        Quaternion q2 = Quaternion.LookRotation(new Vector3(0, 0, -1));

        m_speed += Time.deltaTime * 0.1f;

        if (m_speed > 1)
        {
            m_speed = 1;
        }

        m_cube0.rotation = Quaternion.Lerp(q1, q2, m_speed);    // 线性
        m_cube1.rotation = Quaternion.Slerp(q1, q2, m_speed);   // 球面

RotateToWards方法

1、public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta);

该方法也是一个插值方法,即从返回参数from到to的插值,且返回值的最大角度不超过maxDegreesDelta。maxDegreesDelta是角度值,不是插值系数,当maxDegreesDelta < 0时,将进行逆向插值即从to到from的方向进行插值计算。

        Quaternion q1 = Quaternion.LookRotation(new Vector3(0, 0, 1));
        Quaternion q2 = Quaternion.LookRotation(new Vector3(0, 0, -1));

        m_speed += Time.deltaTime;
        m_cube0.rotation = Quaternion.RotateTowards(q1, q2, m_speed);

 

Quaternion类运算符

Quaternion类涉及到两个Quaternion对象相乘和Quaternion对象与Vector3对象相乘,那么就必须重载"*"运算符。

1、public static Quaternion operator *(Quaternion lhs, Quaternion rhs);

2、public static Vector3 operator *(Quaternion rotation, Vector3 point);

 

两个Quaternion对象相乘

对于两个Quaternion对象相乘主要用于自身旋转变换,例如:

B.rotation *= A.rotation;

B会绕着B的局部坐标系的z、x、y轴按照先绕z轴再绕x轴最后绕y轴的旋转次序,分别旋转A.eulerAngles.z度、A.eulerAngles.x度、和A.eulerAngles.y度。由于是绕着局部坐标系进行旋转,所以当绕着其中一个轴进行旋转时,可能会影响其余两个坐标轴方向的欧拉角(除非其余两轴的欧拉角都为0才不会受到影响)。

        Quaternion q1 = Quaternion.Euler(10, 10, 10);
        Quaternion q2 = Quaternion.identity;

        q2 *= q1;
        Debug.Log(q2.eulerAngles);

        q2 *= q1;
        Debug.Log(q2.eulerAngles);
 

Quaternion对象与Vector3对象

对于Quaternion对象与Vector3对象相乘主要用于自身移动变换,例如

transform.position += tansform.rotation * A;

其中A为Vector3的对象。transform对应的对象会沿着自身坐标系中向量A的方向移动A的模长的距离。transform.rotation与A相乘可以确定移动的方向和距离。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: unity quaternion.identity是Unity中的一个常量,表示一个旋转角度为度的四元数。四元数是一种用于表示旋转的数学工具,它可以更有效地进行旋转计算。在Unity中,quaternion.identity通常用于初始化旋转变量或将物体旋转归零。 ### 回答2: Unity游戏引擎中的quaternion.identity是一个四元数,它表示的是一个没有任何旋转的方向。一个单位的四元数表示一个旋转的方向,而identity四元数则表示没有旋转的方向。 在Unity中,四元数被广泛用于表示物体的旋转,因为它们比欧拉角更不容易出现奇异性,并且更容易执行旋转运算。identity四元数在实现这些旋转运算时也非常有用,因为它可以让物体保持不旋转的状态。 例如,如果一个物体被旋转了一定的角度,但是现在需要恢复到初始状态,可以使用quaternion.identity将其恢复为无旋转的状态。这可以通过将物体的旋转属性设置为quaternion.identity来实现。 另外,quaternion.identity还可以与其他四元数进行插值运算,生成新的旋转四元数,这个新的四元数可以描述一个从无旋转到其他旋转状态的过渡效果。 总之,quaternion.identity是一个非常有用的Unity中的四元数。它表示了一个没有旋转的方向,并且可以通过与其他四元数进行运算实现旋转的效果。在游戏开发中,理解和掌握quaternion.identity的用法对于实现复杂的旋转效果和动画效果至关重要。 ### 回答3: Unity 中的 Quaternion.identity 是一个单位 Quaternion,表示旋转角度为零度,即没有任何旋转。在 Unity 中,Quaternion 被广泛应用于游戏物体的旋转。 Quaternion 是一个四元数表示法,它比欧拉角更稳定和准确。欧拉角可能会遇到万向锁问题,导致旋转不准确,而 Quaternion 可以完美避免这个问题。 当我们把 Quaternion.identity 赋值给一个游戏物体的旋转属性时,它会重置游戏物体的旋转,使它恢复到初始状态,即没有旋转的状态。我们可以这样写代码: ```csharp gameObject.transform.rotation = Quaternion.identity; ``` 这行代码会将 gameObject 对象的旋转重置为单位 Quaternion,即没有旋转的状态。这在游戏开发中非常有用,比如当我们需要重置游戏物体的状态时,或者需要让游戏物体回到初始状态时,可以使用 Quaternion.identity。 同时,Quaternion.identity 也可以作为初始值使用,用于在旋转过程中初始化一个 Quaternion。比如,我们可以这样创建一个 Quaternion 对象: ```csharp Quaternion rotation = Quaternion.identity; ``` 这会创建一个初始旋转为零度的 Quaternion 对象,我们可以在接下来的旋转过程中修改它的值。 总之,Quaternion.identity 是 Unity 中一个非常有用的工具,可以帮助我们控制游戏物体的旋转状态,并且优化游戏物体的旋转计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值