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.mzph.cn/news/600121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文心一言实战大全

"文心一言"是一个基于人工智能的写作助手,它可以帮助用户生成各种类型的文本。以下是一些使用"文心一言"的实战示例: 写博文 如果你是一个博客作者,你可以使用"文心一言"来帮助你生成博文。只需输入你的主题或…

区块链智能合约测试框架Foundry技术指南

在区块链开发领域,智能合约的安全性和可靠性至关重要。鉴于区块链的不可变性,智能合约中的任何错误都可能导致不可逆转的后果,包括重大的财务损失。这凸显了彻底测试的关键重要性。Foundry 是一种 Solidity 测试框架,在这一领域中成为一个强大的工具,为开发人员提供了严格…

Golang如何解决重复提交并发问题

Golang如何解决重复提交并发问题 前言一 .前端防止重复点击二 .后端防止重复插入三. 数据库约束四 通过事物db.Transaction进行处理五 redies防重复点击 前言 在实际开发中,有很多情况出现,其中用户重复提交或多个用户同时操作点击同一个server服务提交…

FreeRTOS移植

目录 一、FreeRTOS简介1.1 初识FreeRTOS1.2 FreeRTOS资料获取1.3 开发环境简介 二、FreeRTOS移植2.1 文件添加2.2 keil工程添加2.3 文件修改 一、FreeRTOS简介 1.1 初识FreeRTOS 首先看一下 FreeRTOS 的名字,可以分为两部分:“Free”和“RTOS”&#xf…

MySQL基础篇(三)约束

一、概述 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。 目的:保证数据库中数据的正确、有效性和完整性。 分类: 注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。 二…

智能分析网关V4太阳能风光互补远程视频智能监控方案

一、背景需求 在一些偏远地区,也具有视频监控的需求。但是这类场景中,一般无法就近获取市电,如果要长距离拉取市电,建设的成本非常高且长距离传输有安全隐患,因此风光互补远程视频监控方案的需求也较多。利用风光电转化…

MyBatisPlus学习二:常用注解、条件构造器、自定义sql

常用注解 基本约定 MybatisPlus通过扫描实体类&#xff0c;并基于反射获取实体类信息作为数据库表信息。可以理解为在继承BaseMapper 要指定对应的泛型 public interface UserMapper extends BaseMapper<User> 实体类中&#xff0c;类名驼峰转下划线作为表名、名为id的…

CentOS 7.6下的HTTP隧道代理配置详解

在CentOS 7.6操作系统中&#xff0c;配置HTTP隧道代理需要一定的技术知识和经验。下面我们将详细介绍如何配置HTTP隧道代理&#xff0c;以确保网络通信的安全性和稳定性。 首先&#xff0c;我们需要了解HTTP隧道代理的基本原理。HTTP隧道代理是一种通过HTTP协议传输其他协议数…

怎么用java写网页?

在Java中&#xff0c;我们通常使用JavaServer Pages (JSP)技术来创建简单的网页。以下是一个简单的JSP页面的示例&#xff1a; jsp复制代码 <% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8"%> <!DO…

Linux习题3

解析&#xff1a; grep&#xff1a;查找文件内的内容 gzip&#xff1a;压缩文件&#xff0c;文件经压缩后会增加 gz&#xff1a;扩展名 find&#xff1a;在指定目录下查找文件 解析&#xff1a; A hosts文件是Linux系统上一个负责ip地址与域名快速解析的文件&#xff0c;以…

gitlab 8.13.0 关闭注册功能

新版本基本都可以在网上找到关闭注册的教程&#xff0c;但是老版本会比较麻烦&#xff0c;可以通过如下路径在网页中设置&#xff08;root 管理员登录&#xff09; ​​​​​​http://ip:port/admin/application_settings 最后保存即可

Java实战项目五:文本冒险游戏

文章目录 一、实战概述二、知识点概览&#xff08;一&#xff09;条件分支与循环结构&#xff08;二&#xff09;面向对象设计&#xff08;三&#xff09;用户交互与事件处理 三、思路分析&#xff08;一&#xff09;系统架构设计&#xff08;二&#xff09;功能模块划分详解 四…

java常见面试题:什么是自动装箱和拆箱(Autoboxing and Unboxing)?

自动装箱和拆箱是Java中的一种特性&#xff0c;它允许基本数据类型和包装类之间自动转换。 自动装箱是指基本数据类型自动转换为对应的包装类对象。例如&#xff0c;当一个基本数据类型数值被赋给一个包装类对象时&#xff0c;Java会自动将这个数值装入对应的包装类中&#xf…

【go语言】select多路选择

select基础知识 select 是 Go 语言中用于处理通道操作的控制结构&#xff0c;它类似于 switch 语句&#xff0c;但专门用于通道的选择。select 语句使得一个 goroutine 可以等待多个通道操作&#xff0c;当其中任意一个通道操作可以进行时&#xff0c;就会执行相应的 case 分支…

Reids原理及简单命令

目录 1.关系数据库与非关系型数据库 关系型数据库 非关系型数据库 关系型数据库和非关系型数据库区别 数据存储方式不同 扩展方式不同 对事务性的支持不同 总结&#xff1a; 2. Redis简介 什么是reids reids优点 reids使用场景&#xff1a; reids快的原因 Redis数…

阿里面试:redis 为什么把简单的字符串设计成 SDS?

面试官:了解redis的String数据结构底层实现嘛? 铁子:当然知道,是基于SDS实现的 面试官:redis是用C语言开发的,那为啥不直接用C的字符串,还单独设计SDS这样的结构呢? 铁子: 其实看得出面试官是想看看,铁子是只停留在redis的使用层面,还是对底层数据结构有过更深入的…

java每日一题——抽红包(答案及编程思路)

前言&#xff1a; 打好基础&#xff0c;daydayup! 题目要求&#xff1a;假设某主播时发起了抢红包活动&#xff0c;五个红包金额分别为9&#xff0c;666&#xff0c;188&#xff0c;520&#xff0c;99999。粉丝按照先来先得&#xff0c;随机抽取&#xff0c;抽完为止&#xff0…

python如何循环读取excel一列中两个单元格之间的数据并写入文本文件?

python如何循环读取excel一列中两个单元格之间的数据并写入文本文件&#xff1f; ━━━━━━━━━━━━━━━━━━━━━━ python如何循环读取excel一列中两个单元格之间的数据&#xff0c;如B2到B22&#xff0c;并写入文本文件&#xff1f; 你可以使用 Python 中的 op…

功能强大且直观的日程和任务管理工具—Things 3 for Mac

在现代生活中&#xff0c;我们面对着繁忙的日程安排和众多的任务&#xff0c;我们需要一款高效的工具来帮助我们管理和组织这些事务。而事务管理的首选工具&#xff0c;非 Things 3 for Mac 莫属。 Things 3 for Mac 是一款功能强大且直观的日程和任务管理工具。它的设计简洁&…

Vue3——element-plus表格组件怎样得到当前行的id

实现方法&#xff1a; <el-table-column property"address" label"操作" show-overflow-tooltip header-align"center" v-slot"scope"><el-button type"success" click"editBtn(scope.row.id)">编辑…