加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

untiy3d Euler 和 Quatertion(在unity中用于处理旋转和方向)

(2016-10-20 16:17:51)

Rotation and Orientation in Unity

最直观的翻译就是unity中的旋转和方向的问题:

3D应用中的旋转通常以两种方式之一表示,即四元素或欧拉角。每个都有自己的用途

和缺点。Unity在内部使用四元素,但在inspector面板中显示等效的欧拉角的值,以方便你编辑。

The Difference Between Euler Angles and Quaternions

Euler Angles

欧拉角具有更简单的表示,即依次应用的XYZ的三个角度值。 为了将欧拉旋转应用于特定对象,每个旋转值依次应用为围绕其对应轴的旋转。

好处:欧拉角有一个直观的“人类可读”格式,由三个角度组成。

好处:欧拉角可以表示从一个方向到另一个方向通过大于180度的转弯的旋转

限制:欧拉角遭受Gimbal Lock (云台锁)当依次应用三个旋转时,第一或第二旋转可能导致第三轴指向与先前轴中的一个相同的方向。 这意味着已经失去了“自由度”,因为第三旋转值不能围绕唯一轴应用。

Quaternions

四元数可以用于表示对象的方向或旋转。这个表示在内部由四个数字(在Unity中称为xyzw)组成,然而这些数字不表示角度或轴,并且通常不需要直接访问它们。除非你特别有兴趣深入研究四元数学,你只需要知道四元数表示三维空间中的旋转,你通常不需要知道或修改xyz属性。

 

就像矢量可以表示位置或方向(其中方向是从原点测量)相同的方式,四元数可以表示取向或旋转 - 其中旋转从旋转“origin”或“Identity“。因为旋转是以这种方式测量的 - 从一个方向到另一个方向 - 四元数不能表示超过180度的旋转。

 

好处:四元旋转不会受到Gimbal Lock(云台锁)的影响。

限制:单个四元数不能表示在任何方向上超过180度的旋转。

限制:四元数的数字表示不是直观可理解的。

Unity中,所有游戏对象旋转在内部存储为四元数,因为利大于弊。

 

然而,在Transform Inspector中,我们使用欧拉角显示旋转,因为这更容易理解和编辑。

输入到检查器中用于旋转游戏对象的新值被“底层”转换为对象的新的四元旋转值。

http://s12/mw690/0066uSabzy75LEXbIvhdb&690Euler 和 Quatertion(在unity中用于处理旋转和方向)" TITLE="untiy3d Euler 和 Quatertion(在unity中用于处理旋转和方向)" />

一个游戏对象的旋转被显示和编辑在inspector中用欧拉角,但在内部存储为一个

四元数。

作为副作用,在检查器中可以为游戏对象的旋转输入例如X0Y365Z0的值。

 这是一个不可能表示为四元数的值,因此当您按下Play时,您将看到对象的旋转值更改为X0Y5Z0(或那里)。

 这是因为旋转被转换为不具有“全360度旋转加5度”的概念的四元数,而是简单地被设置为以与旋转的结果相同的方式定向。

Implications for Scripting (在脚本中的意义)

在处理脚本中的旋转时,应该使用Quaternion类及其函数来创建和修改旋转值。

 在某些情况下,使用欧拉角是有效的,但您应该牢记:

 您应该使用处理欧拉角的四元数类函数 - 检索,修改和重新应用旋转中的欧拉值可能会导致无意 副作用

 

直接创建和处理四元素

Unity Quaternion类有许多函数,允许你创建和操作旋转,而不需要使用欧拉角。 例如:

 

 

 

但是,有时候你需要在你的脚本中使用欧拉角。 在这种情况下,重要的是要注意,你必须保持你的角度在变量,

只使用它们作为欧拉角应用到你的旋转。 虽然可以从四元数检索欧拉角,如果您检索,修改和重新应用,将出现问题。

 

我创建了一个类来测试一些关于欧拉角和四元素正确和错误的示例:

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

 

public class QuaternionAndEuler : MonoBehaviour {

 

    float x = 0;

 

   // Use this for initialization

   void Start () {

  

   }

  

   // Update is called once per frame

   void Update () {

       

   }

 

    void MistakeExample1()

    {

       这里的错误是我们正在修改四元素的X的值
         该值不表示角度,并且不会产生所需的结果

        var rot = transform.rotation;

        rot.x += Time.deltaTime * 10;

        transform.rotation = rot;

    }

 

 

    void MistakeExample2()

    {在这个错误的例子中,我们在获得欧拉角的值,
          然后修改了欧拉角的值,因为这些值都是通过四元素计算的
         这可能遭受gimbal lock

       

        var angles = transform.rotation.eulerAngles;

        angles.x += Time.deltaTime * 10;

        transform.rotation = Quaternion.Euler(angles);

    }

 

 

    void CorrectlyExample()

    我们存储我们的欧拉角在类变量中(也就是x)
        然后我们也仅仅把它应用到欧拉角中,

 

        x += Time.deltaTime * 10;

        transform.rotation = Quaternion.Euler(x,0,0);

    }

}

在动画中的应用:

许多3D创作包以及Unity自己的内部动画窗口允许您使用欧拉角来指定动画期间的旋转。

这些旋转值经常超过四元数表示的范围。 例如,如果对象应当就地旋转720度,则这可以由欧拉角X0Y720Z0表示。 但是这根本不能用四元数值表示。

Unity动画窗口:

Unity自己的动画窗口中,有一些选项允许您指定如何内插旋转 - 使用四元数或欧拉插值。

通过指定欧拉插值,你告诉Unity,你想要的角度指定的全范围的运动。

 然而,使用四元旋转,你只是想要以特定的方向旋转到目的地,Unity将使用四元插值并以最短的旋转距离到达那里。 有关更多信息,请参阅使用动画曲线。

外部动画源:

从外部源导入动画时,这些文件通常包含Euler格式的旋转关键帧动画。

 Unity的默认行为是重新取样这些动画并为动画中的每个帧生成新的四元关键帧,以避免任何关键帧之间的旋转可能超过四元数有效范围的情况。

例如,假设两个关键帧,相隔6帧,X的值在第一个关键帧上为0,在第二个关键帧上为270

在没有重采样的情况下,这两个关键帧之间的四元数内插将在相反方向上旋转90度(-90),因为这是从第一取向到第二取向的最短方式。

但是,通过在每个帧上重新采样和添加关键帧,现在关键帧之间只有45度,因此旋转将正常工作。

 

仍然有一些情况,即使是重采样 - 导入的动画的四元数表示可能不够匹配原来足够,

因此,在Unity 5.3和以上,有关闭动画重采样的选项,所以你可以改为请在运行时使用原始的Euler动画关键帧。

有关更多信息,请参阅Animation import of Euler Curve Rotations

 本文来自Unity官网,仅用于个人笔记

官网链接:https://unity3d.com/cn/



0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有