Unity3D 控制物体旋转详解 —— 自身绕轴旋转、缓慢旋转、鼠标控制旋转、欧拉数和四元数的关系



问题描述:昨天需要实现一个功能是根据指令左转90度或者右转90度,当时脑汁可能是有浆糊吧,居然要用直接赋值rotation,这样一来就要牵扯到eulerAngles和四元数的Euler函数了,结果忙活了好久没解决,bug层出,今天经过详细了解,解决了相关问题,一并把其他关于角度和旋转的知识点整理出来。


一、问题的解决:如何让物体绕自身轴旋转

直接上关键代码:

player_cube.Rotate(-90, 0, 0);

player_cube是获取的需要旋转的物体的Transform,其中-90意味着,在unity面板中 rotation 中的 x 减少90,从而实现旋转;

如果想让物体直接旋转多少度,这个是最方便快捷的方法!


二、缓慢旋转

多见于FPS游戏中使用,用于转换摄像头角度,以下为自己以前做过的例子:(仅作参考)

//获取鼠标移动
mouse_move_velocity.y = Input.GetAxis("Mouse X");
mouse_move_velocity.x = -Input.GetAxis("Mouse Y");
//rote camera
Vector3 target_angle = transform.rotation.eulerAngles + mouse_move_velocity;
//限定角度
//调整周期,限定角度
if (target_angle.x > 180) target_angle.x -= 360;
if (target_angle.y > 180) target_angle.y -= 360;
target_angle = new Vector3(Mathf.Clamp(target_angle.x, X_min, X_max), Mathf.Clamp(target_angle.y, Y_min, Y_max), 0);
//转化四元角度
transform.rotation = Quaternion.Euler(target_angle);

对于限定角度的旋转实现


三、实现鼠标拖拽旋转

以前的项目在另一个硬盘上,找不到相关的示例暂时,这里只说一下思路:

  1. 像第二部分说的那样,获取鼠标移动,当然要判断一下鼠标是否点击了要旋转的物体;
  2. 当获取到鼠标移动的时候,设置移动后所对应的旋转目标;
  3. 利用Rotate实现跟随旋转;
  4. 如果想有渐缓效果可以加额外的中间变量记录,从而达到缓慢的跟随效果,如果需要更精细,可以加animation;

四、欧拉数和四元数之间的千丝万缕

最简单的对比就是,欧拉数是一个三维向量,在Unity的定义中就是个Vector3,而四元数顾名思义则是包含四个参数的量-Quaternion。

关于两者之间的转换:

private Quaternion quaternion;
private Vector3 transform_rotation;
public void Init()
{
    transform_rotation = quaternion.eulerAngles;
    quaternion = Quaternion.Euler(transform_rotation);
}


到这里其实就差不多能满足基本的旋转要求了,但是还有许多细节值得展开学习说明。比如四元数的本质,世界轴和自身轴,等等等等

2019/8/9 更新于鹏城实验室

原文地址:https://www.cnblogs.com/wayne-tao/p/11326005.html

时间: 2024-10-12 03:10:13

Unity3D 控制物体旋转详解 —— 自身绕轴旋转、缓慢旋转、鼠标控制旋转、欧拉数和四元数的关系的相关文章

Unity3D游戏开发之详解 Animation类和Animator类

Unity3D游戏开发之详解 Animation类和Animator类 Animation类 animation组件用于播放动画.可以指定动画剪辑到动画组件并从脚本控制动画播放.在Unity的动画系统基于权重并且支持动画融合,叠加动画,动画混合,标签和完全控制动画播放的各个方面. 如果想播放一个简单的动画,可以使用Animation.Play:如果想在动画之间交叉淡入,可以使用Animation.CrossFade:如果想改变动画模式(循环,一次,乒乓),可以改变动画导入设置里面的动画帧的Wra

IOS6屏幕旋转详解(自动旋转、手动旋转、兼容IOS6之前系统)

IOS6屏幕旋转详解(自动旋转.手动旋转.兼容IOS6之前系统) 转自:http://blog.csdn.net/cococoolwhj/article/details/8208991 概述: 在iOS6之前的版本中,通常使用 shouldAutorotateToInterfaceOrientation 来单独控制某个UIViewController的方向,需要哪个viewController支持旋转,只需要重写shouldAutorotateToInterfaceOrientation方法.

AVL树平衡旋转详解

AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, 2, 3, 4, 5, 6, 7..., n.在BST树中,比较理想的状况是每个子树的左子树和右子树的高度相等,此时搜索的时间复杂度是log(N).可是,一旦这棵树演化成了线型树的时候,这个理想的情况就不存在了,此时搜索的时间复杂度是O(N),在数据量很大的情况下,我们并不愿意看到这样的结果. 现在

unity3d 获取游戏对象详解

原文地址:http://www.xuanyusong.com/archives/2768 我觉得Unity里面的Transform 和 GameObject就像两个双胞胎兄弟一样,这俩哥们很要好,我能直接找到你,你也能直接找到我.我看很多人喜欢在类里面去保存GameObject对象.解决GameObject.Find()无法获取天生activie = false的问题.     private GameObject root ; 我觉得你最好不要保存GameObject ,而是去保存Transf

Unity3d脚本执行顺序详解

欢迎来到unity学习.unity培训.unity企业培训教育专区,这里有很多U3D资源.U3D培训视频.U3D教程.U3D常见问题.U3D项目源码,我们致力于打造业内unity3d培训.学习第一品牌. 在调用脚本的时候遇到下面报错情况: NullReferenceException: Object reference not set to an instance of an object 意思就是:未将对象引用设置到对象的实例脚本内部的 Start()函数并不能作为构造的形式,因为在同一个对象

Unity3D中的Coroutine详解

Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutine程序执行流程怎么那么奇怪? unity中的coroutine原理是什么,怎么实现的? 使用unity的coroutine需要注意什么问题? 一.yield的在几种语言中的程序执行特性: Lua中的yield是使得协同函数运行->挂起并且传递参数给resume.resume使得协同函数挂起->运行

【OpenCV】图像旋转详解,边缘用黑色填充

项目要用到图像旋转,OpenCV里面居然没有专门封装好的函数,只好自己写了.根据<learnning OpenCV>发现效果不是很理想,旋转后图像大小不变,可是图像却被裁减了. 例子如下: int main( int argc, char** argv ) { IplImage* src=cvLoadImage("C:\\Users\\Liu\\Desktop\\bridge.bmp",1); IplImage* dst = cvCloneImage( src ); int

Chrome调试折腾记_(1)调试控制中心快捷键详解!!!

转载:http://blog.csdn.net/crper/article/details/48098625 大多浏览器的调试功能的启用快捷键都一致-按下F12;还是熟悉的味道;  或者直接 Ctrl> + Shift + J: 直接进入console面板 点击第一张截图圈圈那个进入,看到Shortcuts这个就是了-.快捷键大全 快捷键大全 快捷键有这么以下几大类..且看我一一道来~~~注:All pane是全局快捷键 Console() Ctrl + L : 清除控制台消息 Tab : 自动

【Unity3D/C#】Unity3D中的Coroutine详解

Unity中的coroutine是通过yield expression;来实现的.官方脚本中到处会看到这样的代码. 疑问: yield是什么? Coroutine是什么? unity的coroutine程序执行流程怎么那么奇怪? unity中的coroutine原理是什么,怎么实现的? 使用unity的coroutine需要注意什么问题? 一.yield的在几种语言中的程序执行特性: Lua中的yield是使得协同函数运行->挂起并且传递参数给resume.resume使得协同函数挂起->运行