当前位置: 首页 > news >正文

Unity游戏内相机(主角头部视角)的旋转问题:“万向节锁定”(Gimbal Lock)

前言:

        在Unity中,相机的正前方是Z正半轴,相机的正右方是X正半轴,相机的正上方是Y正半轴。这个很好理解。

        现在,我想要相机看向左前上方45°,你会觉得要怎么做呢?

        如果是我的话,我的第一感觉确实就是先绕相机的Y轴逆时针旋转45度,然后再绕相机的X轴逆时针旋转45度。然后确实是做到了,没错的,大家的第一印象没毛病。

        假设这个时候摄像头视野的正中心有一个苹果,但是苹果的正左侧有一个香蕉,现在我想让相机往左稍微摆动一下,让相机聚焦苹果正左侧的香蕉,于是我们打算绕相机的Y轴再次逆时针旋转10度,试图去对准香蕉。

        奇怪的是,当旋转完毕之后,相机视野正中心并没有靠近香蕉,甚至是远离了香蕉!!!

        越是想纠正,越是远离香蕉!!!

原因:

        经过多次旋转之后,已经改变了相对于相机的局部坐标轴(相机的前、右、上方向),所以原来的方法会失效。

        这种现象被称为“万向节锁定”(Gimbal Lock)。万向节锁定是一个在使用三个欧拉角表示三维空间旋转时可能遇到的问题,尤其是当旋转顺序导致两个旋转轴对齐时。此时,会失去一个旋转自由度,导致无法独立控制某个轴的旋转。

        在Unity等三维图形环境中,当你绕着一个轴旋转一个物体时(比如绕着X轴或Y轴),这个物体的其他轴(比如Y轴和Z轴)也会随之旋转。如果进行多次旋转,这些轴可能会变得对齐或近似对齐,从而导致万向节锁定。在万向节锁定的状态下,本应独立的两个旋转轴因为对齐而实际上合并成了一个轴,使得原本独立的两个旋转方向无法被单独控制。

解决的方法:

1. 用四元数(Quaternion)来表示旋转

        为了解决或避免万向节锁定问题,可以使用四元数(Quaternion)来表示旋转。四元数可以提供不受万向节锁定影响的平滑连续旋转,这也是为什么在Unity等现代三维图形软件中四元数被广泛用于处理旋转。

2.还是喜欢用xyz轴表示旋转

        如果还是想用3个轴来表示旋转的话,可以将这两个旋转分开到两个不同的对象上,可以确保当你旋转其中一个轴时,不会意外地影响到另外一个轴。这样,摄像头的行为就更加可控和预测。在Unity中,为了避免万向节死锁,并使摄像头的控制更加直观和灵活,通常会将摄像头的水平旋转(通常是Y轴)和垂直旋转(通常是X轴)分开处理。

        我的处理方法是,相机这个对象来控制抬头和低头。

        相机的父对象Observer来控制左转和右转。

public float mouseSensitivity = 100f;[SerializeField] Transform observerTf;[SerializeField] Transform cameraTf;private float xRotation = 0f;void Start(){Cursor.lockState = CursorLockMode.Locked;}void Update(){float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;observerTf.Rotate(0, mouseX * Time.deltaTime, 0);cameraTf.Rotate(-mouseY * Time.deltaTime, 0, 0);}

        一个对象控制一个轴的旋转,这样就能避免旋转的时候意料之外的旋转了Z轴,导致视线不可控的问题。这样一来,相机视线的控制就变得得心应手了。

http://www.lryc.cn/news/276527.html

相关文章:

  • Keras实现seq2seq
  • 1080p 1k 2k 4k 8k 分辨率,2K就不应该存在。
  • 接口芯片选型分析 四通道差分驱动可满足ANSI TIA/EIA-422-B 和ITU V.11 的要求 低功耗,高速率,高ESD
  • 使用.Net nanoFramework获取ESP32板载按键的点击事件
  • 安全远控如何设置?揭秘ToDesk、TeamViewer 、向日葵安全远程防御大招
  • Spring AOP(详解)
  • Linux系统编程之进程
  • Vue中使用require.context自动引入组件的方法介绍
  • Java 监控诊断利器 Arthas monitor/watch/trace 命令使用详解
  • 论文阅读:基于MCMC的能量模型最大似然学习剖析
  • 【Verilog】期末复习——设计一个带异步复位端且高电平有效的32分频电路
  • 基于springboot的java读取文档内容(超简单)
  • K8S亲和性,反亲和性,及污点
  • 2024年,AI、Web3、区块链、元宇宙:有没有“相互成就“的可能性?
  • Mac电脑好用的修图软件:Affinity Photo 2中文 for Mac
  • 数据结构之Radix和Trie
  • ctrl+c与kill -2的区别
  • 每日算法打卡:分巧克力 day 9
  • Golang switch 语句
  • 可碧教你C++——位图
  • 2024年虚拟DOM技术将何去何从?
  • 基于51单片机的恒温淋浴器控制电路设计
  • 【redis】redis的bind配置
  • C++ 继承
  • 了解ASP.NET Core 中的文件提供程序
  • 竞赛保研 基于深度学习的人脸性别年龄识别 - 图像识别 opencv
  • JavaScript音视频,JavaScript简单获取电脑摄像头画面并播放
  • 《JVM由浅入深学习【五】 2024-01-08》JVM由简入深学习提升分享
  • FastDFS之快速入门、上手
  • Vue 中的 ref 与 reactive:让你的应用更具响应性(中)