[Unity 3D] Quaternion.LookRotation

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lijing_hi/article/details/7272089
  此函数作用是生成一个四元数表示的三维朝向,然后可以直接把这个朝向赋给游戏对象来变更其朝向,也可以通过线性插值(Quaternion.Slerp 和 Quaternion.Lerp)来实现游戏对象从当前朝向转到这个新生成的朝向上来。很方便也很好玩的东西,可就是两个参数理解起来太让人头大了……
  官网对此函数的参数和解释如下:
Quaternion.LookRotation  

static function LookRotation (forward : Vector3, upwards : Vector3 = Vector3.up) : Quaternion


Description

Creates a rotation that looks along forward with the the head upwards along upwards

Logs an error if the forward direction is zero.


没看懂……没办法,只好在Unity里动手做了一个小场景来试验。试验内容很简单:创建一个第一人称角色控制器,再创建一个浮空的方块,通过在方块的脚本中使用 Quaternion.LookRotation 和 Quaternion.Slerp 来让方块一直保持以正面朝向摄像机(也就是玩家视野),在游戏中当玩家移动时,方块也以一定的速率调整自己的朝向以保持面向玩家;准备妥当之后就运行场景,绕着这个方块猛转圈,并且调整 LookRotation 里的参数取值,观察取值不同时方块旋转的行为变化。折腾了半天,终于找到了一点规律。

  旋转都是相对的,需要有参照系。在三维游戏世界中,一个全局的参照系就是世界坐标系。我们通常说的一个物体从一个朝向转到另一个朝向,其实就是从面向世界坐标系下的一个方向,转变为面向世界坐标系下的另一个方向。这里如果再把 x,y,z 轴的定义加上的话,就变成了:物体自身坐标系的 +z 轴指向,从与世界坐标系下的一个矢量方向相同,转变为与世界坐标系下另一个矢量方向相同。这个说法与我们平时的经验基本一致,但是却少了一点东西。
  三维空间中的旋转有三种方式,对应三个坐标轴——绕x轴的旋转(yaw),绕y轴的旋转(pitch)和绕z轴的旋转(roll),任何旋转都可以由这三种旋转组合出来。按照坐标轴通常的定义,+z 轴方向其实就是物体“面朝”的方向(游戏世界里,一个角色面朝的方向通常就是这个角色自身坐标系的 +z 轴方向)。现在再来看之前的那个说法“物体自身坐标系的 +z 轴指向,从与世界坐标系下的一个矢量方向相同,转变为与世界坐标系下另一个矢量方向相同”,+z 轴指向改变——+z 轴指向可以变成指向空间中的任何一个方向,但这却只涉及到绕 x 轴的旋转和绕 y 轴的旋转,那么绕 z 轴自身的旋转呢?绕 z 轴旋转其实就是面朝方向不变时本体翻转,基本可以认为是侧向翻倒。而就我们的日常经验来说,要面朝一个方向,通常只需要抬头、低头、左转、右转就行了,很少会侧倒。假如我们不想让一个物体在旋转时发生侧向翻倒,那么就需要对物体三维旋转加上一个约束,限制一个旋转自由度(绕 Z 轴旋转的自由度)。

  现在来看 LookRotation 的两个参数,第一个参数 forward,是一个三元组,也就是三个浮点数的组合,这个三元组可以确定世界坐标系下的一个点,从世界坐标系的坐标原点到这个定点就构成了一个三维空间矢量,当我们忽略这个矢量的长度时,它就退化为一个纯粹的方向指示,换句话说,这第一个参数 forward 确定了一个世界坐标系下的方向,而这个方向就是物体转动后 +z 轴所要指向的方向;第二个参数 upwards,也是个三元组(之前没看懂就是没看懂在这个参数上,一致闹不明白这个三元组是干啥用的),这个三元组同样可以确定一个世界坐标系下的方向,物体转动后 x 轴必须与这个方向垂直(如果转动前物体的x轴不满足此条件,那么物体除了改变朝向外还会绕 z 轴旋转以确保转动结束后 x 轴与此方向垂直)。
  假如,我们现在给出两个三元组,那么就定下了世界坐标系下的两个方向——方向 A 和方向 B,然后用 LookRotation 依照这两个三元组生成一个旋转,并将这个旋转应用到一个游戏中的物体上去,那么游戏中的这个物体就会先将自己的面朝方向转到与方向 A 一致,然后绕自己的 z 轴旋转,直到自己的x轴与方向 B 垂直为止(当然了,在对这个旋转过程应用线性插值时,可以看到上述前后两次旋转其实是同步进行的,也就是在同一次旋转中完成)。这里可以再思考一下,有没有可能出现这样的情况:不管物体怎么绕 z 轴转,x 轴都无法与 B 方向垂直。答案是:不可能。因为,既然是绕 z 轴旋转,那么 x 轴的旋转轨迹就构成了一个与 z 轴垂直的平面,x 轴的方向可以是这个平面上的任意一个方向;而空间中的方向 B 必然会在这个平面上产生一个投影,只要与这个投影的方向垂直,就必然与产生投影的空间方向 B 垂直;既然 x 轴方向可以是这个平面上的任意一个方向,那么它就必然可以找到一个方向与投影垂直,也就是 x 轴必然可以找到一个方向与这个方向 B 垂直。

  让我们稍微注意一下 LookRotation 的第二个参数的默认值——Vector3.up,这个三元组所定义的世界坐标系方向,其实就是世界坐标轴 +y 的方向,而与世界坐标轴 +y 垂直的方向其实就是任意的水平方向。那么在默认情况下,使用 LookRotation 生成的旋转会使物体一直保持 x 轴指向水平方向,这恰好就是前面说到的我们通常生活经验中的转向体验(抬头,低头,左转,右转)。
展开阅读全文

没有更多推荐了,返回首页