声明:此篇文章是个人学习笔记,并非教程,所以内容可能不够严谨。可作参考,但不保证绝对正确。如果你发现我的文章有什么错误,非常欢迎指正,谢谢哦。

目录

  • 1 奇怪的现象
    • 1.2现象一
    • 1.2 现象二
    • 1.3 现象三
  • 2 万向节(Gimbal)和万向节锁(Gimbal Lock)
    • 2.1 万向节
    • 2.2 欧拉角和万向节的关系
    • 2.3 万向节锁
      • 2.3.1 什么是万向节锁
      • 2.3.2 如何避免万向节锁
  • 3 解释奇怪的现象
    • 3.1 现象一
    • 3.2 现象二
    • 3.3 现象三
    • 3.4 补充现象四
    • 3.5 补充现象五
  • 4 总结
    • 4.1 rotation值的含义
    • 4.2不同的万向节示例图
      • 第一种图示
      • 第二种图示
      • 相同点
    • 4.3最后
  • 5 推荐文章

1 奇怪的现象

Unity的Inspector面板上的rotation是欧拉角,简单来说欧拉角由三个旋转值组成。当刚开始接触Unity时,在Inspector面板上看到Transform组件,会想当然的认为它的rotation要么是指物体绕其惯性坐标轴的旋转度数,要么是物体绕其局部坐标轴的旋转度数。简简单单,X分量就是绕X轴,Y分量就是绕Y轴,Z分量就是绕Z轴而已嘛。

但是当我们试着调整Inspector面板上的rotation时,有时候又会出现奇怪的现象。

1.2现象一

物体旋转既不是绕自身坐标轴旋转,也不是绕惯性坐标轴旋转。

显示的自身坐标轴 显示的惯性坐标轴 Inspector面板

1.2 现象二

有时候,我们直接在场景中调整物体的单个旋转轴(无论惯性坐标轴还是自身坐标轴),但在Inspector面板上却能看到rotation三个数值在同时变化。

场景 Inspector面板

1.3 现象三

更严重的是,有时候会出现一个旋转方向丢失的现象,比如当我们将X旋转90°,再去调整Z和Y的值时会发现:调整Z和Y的效果一样,也就是说我们三个旋转方向变两个了。

将X旋转至90°,再旋转Z轴 将X旋转至90°,再旋转Y轴

为什么会出现这些奇怪的现象,难道是因为Unity出了什么Bug?在解决这个问题之前,先要了解一下万向节。

2 万向节(Gimbal)和万向节锁(Gimbal Lock)

2.1 万向节

如果以前没有了解过万向节,可以看这里:万向节和万向节锁

万向节有三个坐标轴X,Y,Z,刚开始时,三个坐标轴是相互垂直的,这似乎很常见。

但要注意的一点是,它的三个坐标轴有父子关系,父轴的转动会带动子轴的转动,类似于我们在Unity的Hierachy面板上构建的父子关系(如下图)。试着排列三个坐标轴的父子关系,会发现三个轴的父子关系有6种,xyz\xzy\yxz\yzx\zxy\zyx,在不同的应用场景中,人们会采用不同的关系。下面以yxz为例子:

现在假设三个轴的层次关系是这样的: Z在最底层,X是Z的父项,Y是X的父项。也就是说,当我们旋转万向节中的三个轴时,会有以下现象:
Z轴旋转时,另外两个轴不旋转
X轴旋转时,Z轴随X轴旋转而旋转(相对静止),Y轴不动
Y轴旋转时,X,Z都随Y轴旋转而旋转(相对静止)
文字性的描述可能不够清晰,下面的图来自我自己在Unity中编写的万向节模拟系统,物体的旋转使用万向节来实现(其中蓝色的环表示物体的Z旋转轴,红色表示X,绿色表示Y):

旋转的轴 图片 描述
Z 蓝色的轴是Z轴,当旋转Z轴时,X和Y轴保持原有状态不动。因为Z轴在最底层。
X 红色的轴是X轴,因为Z轴是X轴的子项,所以当旋转X轴时,Z轴会随之运动(保持相对静止)。而Y轴保持不动
Y 绿色的轴是Y轴,因为X轴是Y轴的子项,而Z轴是Y轴子项的子项,所以旋转Y轴时,X和Z均会随之旋转从而与Y轴保持相对静止

2.2 欧拉角和万向节的关系

欧拉角内部就是使用的万向节的规则(为什么使用这种规则,为什么不采用三个轴互不影响的策略,可以考虑参考我的下一篇笔记)。可以想象成每个游戏物体有一个隐藏的万向节坐标系统(当然,这是不准确的,这里这么说只是为了帮助理解),就像上面图上的飞机一样。而Inspector面板上的rotation就是欧拉角,也就是采用的万向节的规则。

2.3 万向节锁

2.3.1 什么是万向节锁

万向节的特点是“轴与轴之间存在父子关系,每个轴对另外两个轴的影响各不相同”,也正是因为这个特点,导致出现了一些缺点。
比如当我们将X轴旋转90°后,Z轴和Y轴会变成平行状态,然后我们会发现旋转Z轴和Y轴的效果竟然是一模一样的,这就导致当我们想让图中的飞机实现转向操作时就找不到轴了(这似乎与我们的直觉相违背,三个轴变成了两个)

将X轴旋转90° 旋转Z和Y对物体的旋转效果一样 利用万向节中的轴无法完成的旋转

2.3.2 如何避免万向节锁

3 解释奇怪的现象

前面提到,欧拉角运用的就是万向节的规则。经过我的实验证明,Unity中的欧拉角采用的是yxz的层次关系(即y在最外层,如上面的例子),Inspector面板上显示的并不是物体绕自身局部坐标轴旋转的度数,也不是绕惯性坐标轴旋转的度数,而是隐藏的万向节旋转轴旋转的度数。那么一切都说得通了,真相只有一个!

3.1 现象一

物体旋转既不是绕自身坐标轴旋转,也不是饶世界坐标轴旋转。

解释:这是因为物体绕得是万向节的三个轴,既不同于Unity物体自身坐标轴也不同于惯性坐标轴。

3.2 现象二

有时候,我们直接在场景中调整物体的单个旋转轴(无论惯性坐标轴还是自身坐标轴),但在Inspector面板上却能看到rotation三个数值在同时变化。

场景中的旋转轴要么是使用的物体局部坐标系,要么使用的是惯性坐标系,这二者与物体的万向节坐标系不同。当使用场景中的旋转轴进行旋转时,Unity内部应该是使用的四元数进行处理,然后将其转换为欧拉角(万向节坐标系)的结果显示在Inspector面板上。等价转换之后,可能旋转场景中一个轴的效果需要动用欧拉角的三个轴。

3.3 现象三

更严重的是,有时候会出现一个旋转方向丢失的现象,比如当我们将X旋转90°,再去调整Z和Y的值时会发现:调整Z和Y的效果一样,也就是说我们三个旋转方向变两个了。

这一现象已经在前面解释过了,物体隐含有一个万向节系统, 有些情况下就会出现万向节锁(Gimbal Lock)

3.4 补充现象四

当我们在Inspector面板上按照Z、X、Y的顺序调整rotation的值时会发现,此时场景中物体的旋转效果是绕着物体的惯性坐标轴进行旋转的。这是因为初始状态下(0,0,0),物体的万向节系统的三个轴是和物体的惯性坐标轴重合的,旋转Z轴不影响X,Y轴的位置和角度,所以旋转完Z轴后,X、Y轴依然与惯性坐标轴重合。

如果你发现结果和我说的不一样,可能要检查一下物体中心和坐标轴的设定是不是如此:

3.5 补充现象五

当我们在Inspector面板上按照Y、X、Z的顺序调整rotation的值时会发现,此时场景中物体的旋转效果是绕着物体的局部坐标轴进行旋转的。这是因为初始状态下(0,0,0),物体的万向节系统的三个轴不仅是和物体的惯性坐标轴重合,也是和物体的局部坐标轴重合的。旋转Y轴时会带动X和Z轴旋转,三个轴保持相对静止,这和局部坐标轴是一样一样滴。

4 总结

4.1 rotation值的含义

最后再缕一缕关于Unity中欧拉角的思路。

欧拉角由三个旋转值组成,三个旋转值会根据万向节的规则确定。Unity中Inspector面板上的rotation的三个值对应的是物体的欧拉角,即通过万向节规则确定的三个旋转值。当我们调节Inspector面板上的rotation的值时,Unity根据万向节规则计算出物体当前的朝向。

4.2不同的万向节示例图

我在不同的文章或者视频中看到了两种万向节的示例图,第一次见感觉这两种万向节似乎相互矛盾,但二者其实本质上是一样的。

第一种图示

这张图示是我在维基百科英文版Wikipedia中看到的,它的旋转方式是让环绕着横插过环的轴进行旋转的。

第二种图示

这种图示是我在讲解万向节锁的视频中看到的,也是上面我自己做的图中采用的方式,即像轮胎一样沿着环进行旋转。这里就懒得放图了。

相同点

这两种不同的旋转方式并不影响它们表达相同的本质:父轴的旋转会带动子轴的旋转,而子轴的旋转并不带动父轴的旋转。
另外,我还在一些文章中看到了最里层的轴会带动外层的轴旋转,外层的轴不会带动里层的轴旋转(和上面相反),其本质也是一样一样滴。

4.3最后

这里Unity中关于欧拉角和万向节的讨论依然不够深入,停留在表面的理解上。我将在我的下一篇文章中说说我对“欧拉角为什么会符合万向节的规则”的理解。

5 推荐文章

①清晰易懂的万向节和万向锁的视频(前面已经提到): https://v.youku.com/v_show/id_XNjk1MTkzMTM2.html#paction

②大佬关于欧拉角的讲解文章:
Ⅰ.https://blog.csdn.net/andrewfan/article/details/60866636
Ⅱ.https://blog.csdn.net/AndrewFan/article/details/60981437#comments_14584533

【Unity学习笔记】Unity中的欧拉角(Euler Angle)和万向节(Gimbal)相关推荐

  1. 【Unity学习笔记】为什么欧拉角(Euler)会符合万向节(Gimbal)规则?

    声明:此篇文章是个人学习笔记,并非教程,所以内容可能不够严谨.可作参考,但不保证绝对正确.如果你发现我的文章有什么错误,非常欢迎指正,谢谢哦. 0 引言 在我的上一篇笔记中,我主要关注点在" ...

  2. Unity学习笔记——Unity基础一:unity界面、场景、游戏物体、组件等基本概念

    一.unity界面 如下图,unity最主要的界面为Scene(场景视图).Hierarchy(层级视图).project(工程视图).Inspector(检视视图) project--工程视图 当前 ...

  3. unity学习笔记——unity组件的从属关系

    unity项目组建:项目--场景--游戏对象--组件--属性 (unity是面向组件开发游戏的) 以下这张图,就很好地总结了unity中各组件之间的从属关系: 下面这张里都是一些比较常见的unity组 ...

  4. [Unity学习笔记]2D游戏中的触碰/OnMouseDown

    [Unity学习笔记]2D游戏中的触碰/OnMouseDown 这种情况多用于2D游戏的触屏 1.给2D游戏对象加上collider 2D,让其能够被检测到

  5. 木木的Unity学习笔记(四)—— Unity中的柏林噪声(Perlin Noise)

    木木的Unity学习笔记(四)-- Unity中的柏林噪声 柏林噪声是一个非常强大算法,经常用于程序生成随机内容,在游戏和其他像电影等多媒体领域广泛应用.算法发明者Ken Perlin也因此算法获得奥 ...

  6. 【Unity学习笔记】[Unity中文课堂教程] C#中级编程代码

    [Unity学习笔记][Unity中文课堂教程] C#中级编程代码 最近想补一补C#基础,Unity官方的C#中级编程教程质量很高,于是开个帖子把跟着敲+记录了部分价讲解和我自己的理解的代码存在这 原 ...

  7. Unity学习笔记:Unity 3D 飞机大战

    Unity学习笔记:Unity 3D 飞机大战 1.打开unity软件后,首先新建Quad作为背景,导入飞机模型,并为其添加刚体 然后创建C#脚本,挂载到飞机上. 2.给飞机创建子弹,让子弹成为预制体 ...

  8. Unity学习笔记(4)-----粒子效果的实现

    Unity学习笔记(4)-–粒子效果的实现 一.效果展示 下面用若干张张动图展示效果: 大概就是这样,并不是很难. 实际效果要比图中的好一点(顺畅得多). 实现步骤 大致可以分为如下几个步骤,然后逐个 ...

  9. Unity学习笔记1 简易2D横版RPG游戏制作(一)

    这个教程是参考一个YouTube上面的教程做的,原作者的教程做得比较简单,我先参考着做一遍,毕竟我也只是个初学者,还没办法完全自制哈哈.不过我之前也看过一个2D平台游戏的系列教程了,以后会整合起来,做 ...

最新文章

  1. LeetCode 1119. Remove Vowels from a String--C++,Java,Python解法
  2. 构建城市大脑的未来标准,9个值得探索的规范
  3. HAProxy客户端IP地址的透传
  4. jquery插件开发;(function ( $, window, document, undefined ){}(jQuery, window,document)分析
  5. 5个IO口扫描25个按键的解决方法(转帖)
  6. C++函数中那些不可以被声明为虚函数的函数
  7. Android 中基本图像绘制
  8. 给微软的依赖注入框架写一些扩展方法
  9. LCP 1. 猜数字
  10. 智慧发电厂+智能发电厂web端平台管理系统+Axure高保真智慧电厂系统+能耗管理+告警管理+生产监控+安防设备管理+运维设备管理+监控面板+系统管理+智慧电厂+电厂系统+axure源文件+rp原型
  11. 7-2 玩转二叉树 (25分)_2-1!72分钟绝杀!西乙黑马踢疯了,西班牙人+武磊却迎利好...
  12. 计算机英语课堂活动总结,英语活动总结(精选8篇)
  13. HTML嵌入百度地图
  14. 连接计算机和网线之间的设备,网线的制作及双绞线与设备之间的连接方法
  15. ViewBinding和DataBinding的区别
  16. 安防监控流媒体服务器对接宇视摄像机配置OCX插件安装时出现Failed to register ocx, error code 14001错误问题分析
  17. 第六周作业 百词斩对比可可英语
  18. 如何编写好的用户手册?
  19. iOS 开发 - 播放器Demo开发记录
  20. GitHub改名字和修改仓库名的方法和注意事项 git remote set-url origin xxx

热门文章

  1. Rust的前景怎么样?值不值的学—Rust对比、特色和理念
  2. 联想3650服务器配置信息,【联想x3650参数】联想x3650系列服务器参数-ZOL中关村在线...
  3. smartq ten3 android4,智器(SmartQ)Ten3 MID视频测试评测-ZOL中关村在线
  4. 一个数据分析师,在公司里的主要职责是什么?
  5. Mac系统显示已连接(可以打开qq)但是无法打开浏览器解决方案
  6. 湖北大学计算机系2020录取分数线,2020湖北大学本科投档录取分数线
  7. 重庆各大学计算机专业的录取分数线,重庆各高校历年录取分数线+王牌专业汇总!填报志愿必看!...
  8. Acwing寒假每日一题(一)笨拙的手指
  9. 手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)
  10. 湖南省第六届大学生计算机程序设计竞赛---弟弟的作业