对Unity中的欧拉角的理解

2023-11-08

【前言】

欧拉角对人来说是十分直观的,很适合人机交互中,但不适用于插值和迭代。

在说到欧拉角时有两点非常重要:旋转方式和旋转顺序

【旋转方式】

首先要区分每次旋转是绕固定轴旋转的,还是绕旋转之后的轴旋转的。

绕固定轴旋转就是旋转过程中XYZ轴不变,绕旋转之后的轴旋转表示每次旋转时XYZ改变了。

在Unity中绕固定轴旋转可以看做是绕世界坐标系旋转。看下图中的鲨鱼的Transform中,面板上显示的Rotation为(0,0,0)。在场景中由于我们选择的是Global,相当于绕固定轴旋转。(这是鲨鱼的初始图)

现在我们把鲨鱼的Rotation改为(0,90,0),显然我们的意思是绕Y轴正方向逆时针旋转了90°。(这里要注意旋转正负角度时是如何旋转的,一般来说逆时针旋转为正值,顺时针旋转为负值。)

注意看鲨鱼身上的坐标轴没有变。

现在把Global改为Local,再看鲨鱼身上的坐标轴,蓝色的Z轴和红色的X轴变了。这就是绕旋转之后的坐标轴旋转,下次再旋转时以这个新的坐标轴为准。

【旋转顺序】

绕固定轴旋转时,分别绕X、Y、Z旋转90°(左图)和分别绕Z、Y、X旋转90°(右图)所得结果不同。(鲨鱼的初始图看上面)

绕旋转之后的轴旋转时,同样地,分别绕X、Y、Z轴旋转90°(左图)和分别绕Z、Y、X旋转90°(右图)所得结果仍然不同。

因而,在用欧拉角表示旋转时,需要先声明旋转顺序,否则,按照不同的旋转顺序得到的结果不同。

【Unity中的旋转方式和旋转顺序】

transform.Rotate (Vector3 eulers, Space relativeTo= Space.Self);

在Unity中旋转物体时,我们通常会用到Rotate,官网文档说的是绕固定轴按照ZXY顺序旋转。固定轴有两个选项,世界空间的轴向,模型自身的轴向。这意味着:

代码A       transform.Rotate(new Vector3(60, 45, 90),Space.Self);

代码B        transform.Rotate(new Vector3(0, 0, 90), Space.Self);
                 transform.Rotate(new Vector3(45, 0, 0), Space.Self);
                 transform.Rotate(new Vector3(0, 60, 0), Space.Self);

这两者所得结果不同,在A中是按照当前模型的轴向先绕Z轴旋转90°,再绕X轴旋转45°,再绕Y轴旋转60°。在B中,先按照当前模型的轴向旋转90°,此时模型自身的轴向改变了;之后以改变了的轴向再旋转,绕X轴旋转45°,旋转后,模型自身的轴向又改变了;最后,绕又改变的轴向绕Y轴旋转60°。

 

代码C:   transform.Rotate(new Vector3(60, 45, 90),Space.World);

代码D:   transform.Rotate(new Vector3(0, 0, 90), Space.World);
                transform.Rotate(new Vector3(45, 0, 0), Space.World);
                transform.Rotate(new Vector3(0, 60, 0), Space.World);

这两种所得结果相同,因为每次都是按照世界空间的轴向来旋转。(注:D中的顺序不能改变,否则得到的结果也不一样,因为顺序改变了相当于你改变了旋转顺序,虽然Unity在执行每个Rotate时都按照ZXY的顺序来执行的。)

【面板中的Rotation】

我们都知道面板这里的Rotaton表示欧拉角,X的值表示绕X旋转多少度,Y的值表示绕Y旋转多少度,Z的值表示绕Z旋转多少度。在这个面板中,对于(60,45,90)这个欧拉角来说,无论你按照XYZ、ZXY、ZYX等任何顺序输入,你会看到模型的结果都是一样的。为什么会这样?上文不是说不同的旋转顺序会导致不同的结果吗?

这是因为Unity内部,对于当前面板上的欧拉角,其都是先从(0,0,0)开始按照ZXY的顺序旋转(计算)得到的。也就相当于模型初始的欧拉角的(0,0,0),然后执行了  transform.Rotate(new Vector3(60, 45, 90),Space.Self)。

(如果模型在(0,0,0)时的坐标系与世界坐标系相同,那么按照Space.Self和Space.World旋转的结果是一样的。否则会出现差别,所以在做模型时要求模型坐标系与Unity世界坐标系相同。)

当你按照XYZ顺序输入的时候,你只能一个个地输入。先输入X,此时面板上为(60,0,0),Unity按照ZXY的顺序从(0,0,0)开始计算得到一个结果。然后输入Y,此时面板上为(60,45,0),Unity按照ZXY的顺序从(0,0,0)开始计算得到一个结果,而不是从(60,0,0)开始计算。然后输入Z····

所以,到这里你就可以理解为什么输入顺序不同最后结果都一样了吧。

这是你输入的情况,当你左右滑动连续改变X、Y、Z的值的时候,实际上也都是从(0,0,0)开始计算得到的结果的。因为算得足够快,所以你在场景中看到模型也是连续旋转的。

也许多数时候,你滑动X或Y或Z的值,模型确实是在自身坐标系下绕X(或Y或Z)的情况来旋转的,但有时候就不是这样。

例如,先设置Local,确保模型的Rotation在(0,0,0)时模型坐标系与世界坐标系一致。之后将Rotation设置为(0,0,90)。此时,你再滑动X,你会看到模型不是绕X轴旋转的;你滑动Y,你会看到模型不是绕Y轴旋转的。

这是为什么呢?为什么模型没有按照你想象的方式旋转呢?

因为模型的Rotation是从(0,0,0)开始计算的,因为算得足够快,所以在人眼看来模型就是跟着你滑动的X或Y或Z连续变化的。

这会导致万向锁的问题。

【欧拉角的万向锁】

实际上无论是绕固定轴还是绕旋转之后的轴旋转,无论你怎么旋转,都不会导致万向锁的问题。所以,你不用奇怪,你感觉无论怎么旋转都不会导致万向锁是正确的。

你之所以会观察到万向锁的现象是由于Unity计算欧拉角和人习惯计算欧拉角的方式不同所导致的。模型当前的欧拉角为(60,45,0),要变为(60,45,90)时。Unity会从(0,0,0)变到(60,45,90);而人从(60,45,0)变到(60,45,90)。两者的计算方式不同,而你在Unity中看见的结果是按照Unity自身的方式计算得到的,不是按照你想向的方式计算得到的,所以你会看见让你难以理解的万向锁的问题。

下图展示了万向锁的问题,你会发现无论怎样滑动Y、Z,鲨鱼始终是在世界坐标系的XZ平面。按照人的计算方式,滑动Y时鲨鱼的尾巴应该会朝上的,但没有。

由于Unity是按照固定轴按照ZXY的顺序来旋转的,所以按照Unity的计算方式,总是最后再绕Y轴旋转。所以,当你滑动Y,连续改变欧拉角时,看来像是再绕着世界坐标系的Y轴旋转,而不是绕模型的Y轴来旋转。所以你在Unity中,无论XZ的值时怎样的,只要你滑动Y,Unity计算欧拉角的方式给你呈现的视觉效果就是像围绕世界坐标系的Y轴来旋转一样。

而当你滑动Z时,由于Unity总是先旋转绕Z轴旋转的,所以给你呈现的视觉效果是滑动Z时在场景中看到模型真的在绕模型的Z轴旋转。而有时你滑动X呢,你会发现模型既不绕世界坐标系的X轴旋转,也不绕模型坐标系的X轴旋转。

因而,当模型的X为90时,使得模型坐标系的Z轴和世界坐标系的Y轴在同一条线上,所以你无论怎样滑动Y都看不到鲨鱼尾巴立起来的视觉效果。

那么为什么计算欧拉角时都要从(0,0,0)开始算呢?这个问题还没有搞明白,以后在补充。

【参考】

https://blog.csdn.net/fengya1/article/details/50721768

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对Unity中的欧拉角的理解 的相关文章

  • 一些个人常用的网站网址

    一些个人常用的网站网址 GitHub https github com Gitee https gitee com 1 书栈网 https www bookstack cn explore cid 27 tab popular 2 Unit
  • Unity3D之Rigidbody

    目录 常用的Rigidbody属性和方法 rigidbody AddForce rigidbody AddTorque rigidbody velocity rigidbody angularVelocity rigidbody Sleep
  • UE5学习笔记(一)——界面功能梳理&第一天知识点记录

    学习UE5的第一步 是软件安装 默认是安装好的 由于安装没有太多技术含量 所以就没有专门做记录 这里有个注意点 虚幻引擎是整合在Epic games launcher中的 也就是说开发引擎内嵌在游戏平台上 打个比方 就是如果你要下unity
  • 1.17 从0开始学习Unity游戏开发--场景切换

    前面的所有文章我们都在一个固定的游戏场景内进行开发 在最开始介绍场景这个概念的时候就已经提及 这个场景可以是一张地图 或者是一个对战房间等等 所以显然这个场景可以有多个 并且可以从一个场景切换到另外一个场景 那么在Unity中如何进行场景切
  • Unity 分块延迟渲染01 (TBDR)

    现代移动端图形体系结构的概述 现代SoC通常会同时集成CPU和GPU CPU被用于处理需要低内存延迟的序列 大量分支的数据集 其晶体管用于流控制和数据缓存 GPU为处理大型 未分支的数据集 如3D渲染 晶体管专用于寄存器和算术逻辑单元 而不
  • Unity中级客户端开发工程师的进阶之路

    上期UWA技能成长系统之 Unity高级客户端开发工程师的进阶之路 得到了很多Unity开发者的肯定 通过系统的学习 可以掌握游戏性能瓶颈定位的方法和常见的CPU GPU 内存相关的性能优化方法 UWA技能成长系统是UWA根据学员的职业发展
  • Unity 粒子特效、材质发光 HDR ShaderGraph图文教程[完成lit发光设置]

    效果如图 准备工作 在hdr模式下 关闭Directional Light 相机设置 移动球挂一个点光源作为子节点 设置自行调节 0 创建移动球的材质及shader shader gt 在Project Create Shader Grap
  • Unity中实现倒计时的几种方式

    1 Time time using UnityEngine public class TimeTest MonoBehaviour public float secound 10 void Update Timing private flo
  • GooglePlay提审警告(com.google.android.gms:play-services-safetynet:17.0.0)

    1 Goole在今年6月份出的新政策 不在使用safetynet 而使用Play Integrity API 2 项目本身没有使用过safetynet 3 使用了firebase 查阅资料 解决方案如下 implementation pla
  • Unity学习笔记(一)—— 基础知识

    一 基础知识 1 开发团队组成 2 unity特点 图形界面 所见即所得 入门简单 支持C 比OC C 更友好 js 国内外资源丰富 因为使用的人多 跨平台性好 PC端 移动端等 对VR AR的支持最完善 3 成功案例 游戏 炉石传说 神庙
  • unity工程崩溃资源找回

    1 Unity死机未保存场景 当你在Unity中编辑场景 突然死机时 可以在项目文件目录中找到Temp文件夹 双击文件夹 找到 Backupscenes文件夹 把后缀为 backup的文件后缀改为 unity 然后拖进Unity的Proje
  • Unity打开工程时卡住的问题

    自从Unity升级了一个版本后 Unity打开工程卡住的问题越来越严重了 具体表现为 选择工程后 Unity窗口消失 但进程还在 有时候等个几分钟能出来 有时候等10分钟都不见得能出来 直观感受上看 似乎是Unity加载工程的时候某一步卡了
  • Unity保存图片到相册

    Unity保存图片到Android相册 Java 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
  • unity3d切换场景Application.LoadLevel(1)含义

    Application LoadLevel 1 场景ID
  • 【Unity】运行时创建曲线(贝塞尔的运用)

    Unity 运行时创建线 贝塞尔的运用 1 实现的目标 在运行状态下创建一条可以使用贝塞尔方法实时编辑的网格曲线 2 原理介绍 2 1 曲线的创建 unity建立网格曲线可以参考 Unity程序化网格体 的实现方法 主要分为顶点 三角面 U
  • Unity学习笔记

    一 旋转欧拉角 四元数 Vector3 rotate new Vector3 0 30 0 Quaternion quaternion Quaternion identity quaternion Quaternion Euler rota
  • Unity学习笔记

    一 旋转欧拉角 四元数 Vector3 rotate new Vector3 0 30 0 Quaternion quaternion Quaternion identity quaternion Quaternion Euler rota
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之小地图的制作

    游戏中一般存在小地图系统 实际上就是设置一个新的摄像机放置在玩家的正上方 然后在小地图上显示新摄像机看见的东西就可以了 在小地图上一般存在放大地图和缩小地图的按钮可以方便放大和缩小地图 这些操作是如何实现的呢 接下来直接上核心代码 usin
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接

随机推荐

  • 解决缺少api-ms-win-crt-runtime-

    答主在安装MongoDB的时候 遇到了api ms win crt runtime 1 1 0 dll的问题 历经两天时间终于解决 下面是我的解决历程 首先是这个图 这个是因为没有微软的visual2015c 运行库环境 需要安装 地址 h
  • 刷脸识别改变支付零售日常生活

    据对相貌特征信息的生物辨认技能促就了刷脸付的诞生 并且付宝官方力推刷脸付旨在替代了扫码付出 当然新型的刷脸付款方式关于很多人仍是比较忧虑的 觉得会存在必定安全隐患 那么刷脸付安全吗 有保证吗 那么下面就来解答大家所忧虑的刷脸付安全性问题 早
  • webpack打包入口指定某文件夹内所有js作为入口文件

    webpack config js webpack config js const path require path const glob require glob module exports 指定 packs 文件夹下的 js 文件作
  • Navicat连接MySQL时弹出:1045:Access denied for user ‘root’@’localhost’

    错误原因 当登录MySQL数据库出现 Error 1045 错误时 表明你输入的用户名或密码错误被拒绝访问了 也可能是你的账号不允许从远程登录 只能在localhost本地登录数据库 解决办法如下 用管理员权限打开cmd 并且cd进入mys
  • 点云读取加速c++ ASCii 模式ply 或者txt

    相较于Qt Qtextstream的性能提升十倍 本文点云格式特殊 有需要自行修改即可 QFile dataFile fileName bool ret dataFile open QIODevice ReadOnly QIODevice
  • 浅谈JS的微任务和宏任务(附加面试题)

    Event Loop 因为JS是单线程 就是说 同一个时间只能做一件事 为了协调事件 用户交互 脚本 UI 渲染和网络处理等行为 防止主线程的不阻塞 Event Loop 的方案应用而生 掌握知识点 JS分为同步任务和异步任务 同步任务都在
  • (C语言)指针初识(1)——指针概念及指针类型

    指针 看似是一个令人头疼的问题 静下心来慢慢学习 指针这个主题 分成了几个的板块 比较多 耐心看完 一定会有收获啦 慢慢来 总是需要一个循序渐进的过程 目录 一 什么是指针 二 指针和指针类型 指针类型的意义 结论1 结论2 一 什么是指针
  • vue 和 react的对比

    vue 比react的优缺点 对比1 github 全球开发者星星点赞数量 此数据结果摘取于 2021年3月份 结论 vue 胜出 尤雨溪一个人撑起一个生态 战胜高手林立的巨头公司facebook 相当的传奇 对比2 React VS Vu
  • easyrecovery2023永久免费版激活密钥,手把手教您用EasyRecovery快速恢复数据

    Ontrack EasyRecovery Crack Professional是一个全面的备份和恢复实用程序 可以从多个数据丢失事件中恢复文件 例如常见的意外删除 更严重的 有时是病毒引起的 分区或驱动器格式化 甚至硬盘严重损坏后的数据丢失
  • 阿里Java代码规范

    代码规范 一 编程规约 一 命名风格 二 常量定义 三 代码格式 四 OOP 规约 五 集合处理 六 并发处理 七 控制语句 八 注释规约 九 其它 二 异常日志 一 异常处理 二 日志规约 三 单元测试 四 安全规约 五 MySQL 数据
  • YAML用法详解

    1 简介 YAML YAML Ain t Markup Language j m l 设计目标是方便人类读写 它实质上是一种通用的数据串行化格式 远比 JSON 格式方便 1 1 它的基本语法规则如下 大小写敏感 使用缩进表示层级关系 缩进
  • Spring Cloud之LB-Ribbon调用流程和源码分析(二)

    接着上面的一篇关于Spring Cloud之Open Feign调用流程和源码分析 解析feign在rpc调用的时候lb的组成及底层工作流程 关键组件介绍 ServerList 可以响应客户端的特定服务的服务器列表 ServerListFi
  • python多进程multiprocessing使用,看这篇就够了(二)

    1 上篇都是直接创建Process对象来创建子进程 其实还可以通过继承来创建子进程 来看看Process源码 可以通过承继Process 重写run方法来启动子进程 因为对一个不包括target属性 即当target None时 的Proc
  • C语言栈与队列知识,C语言数据结构基础学习笔记——栈和队列

    之前我们学过了普通的线性表 接下来我们来了解一下两种特殊的线性表 栈和队列 栈是只允许在一端进行插入或删除的线性表 栈的顺序存储结构也叫作顺序栈 对于栈顶指针top 当栈为空栈时 top 1 当栈为满栈时 top MaxSize 1 顺序栈
  • html当鼠标离开时触发事件,html中在鼠标指针移动到元素外时触发的事件属性onmouseout...

    实例 当鼠标指针移动到图像之外时执行一段 JavaScript 浏览器支持 IE Firefox Chrome Safari Opera 所有主流浏览器都支持 onmouseout 属性 定义和用法 onmouseout 属性在鼠标指针移动
  • C++实现——任意进制之间的转换

    include
  • 独孤九剑第七式-物以类聚 人以群分(K-means模型)

    文章适合于所有的相关人士进行学习 各位看官看完了之后不要立刻转身呀 期待三连关注小小博主加收藏 小小博主回关快 会给你意想不到的惊喜呀 各位老板动动小手给小弟点赞收藏一下 多多支持是我更新得动力 文章目录 前言 K means模型讲解 K
  • sparkstreaming读取文件读取不到数据

    今天用了下sparkstreaming读取hdfs文件或本地目录文件 发现文件内容一直不会被处理 使用了下面两种方法都不行 阅读源码并开启DEBUG后发现 textFileStream后面也是调用fileStream方法 并且newFile
  • make时遇到File `Makefile' has modification time 4e+04 s in the future的解决办法

    1 原因 是虚拟机时间和电脑时间不匹配造成 2 解决办法 在VMware 菜单虚拟机 M gt 设置 S gt 选项下设置开启时间同步 然后重启虚拟机 3 若还出现 warning Clock skew detected Your buil
  • 对Unity中的欧拉角的理解

    前言 欧拉角对人来说是十分直观的 很适合人机交互中 但不适用于插值和迭代 在说到欧拉角时有两点非常重要 旋转方式和旋转顺序 旋转方式 首先要区分每次旋转是绕固定轴旋转的 还是绕旋转之后的轴旋转的 绕固定轴旋转就是旋转过程中XYZ轴不变 绕旋