Unity 四元数

  1. 简介

四元数在电脑图形学中用于表示物体的旋转,在unity中由x,y,z,w 表示四个值。

四元数是最简单的超复数。 复数是由实数加上元素 i 组成,其中i^2 = -1 ,。 相似地,四元数都是由实数加上三个元素 i、j、k 组成,而且它们有如下的关系: i^2 = j^2 = k^2 = ijk = -1 , 每个四元数都是 1、i、j 和 k 的线性组合,即:四元数一般可表示为

a + bi + cj + dk 。

  1. 注视旋转

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

传入的两个参数分别代表前方盯着的方向以及自己的上方向。它可以让一个GameObject转动脑袋盯着另一个物体。

向量加减法

public Transform cube; // 位于(0, 3, 0)的一个cube

    public Vector3 target;   // cube的朝向目标, 初始值为(0, 3, 0)

    void Update()

    {

// 注意, 此处Vector3.up并不一定与target - cube.position垂直

        cube.rotation = Quaternion.LookRotation(target - cube.position, Vector3.up);

        Debug.DrawLine(Vector3.zero, cube.forward, Color.blue); // 绘制每根轴

        Debug.DrawLine(Vector3.zero, cube.right, Color.red);

        Debug.DrawLine(Vector3.zero, cube.up, Color.green);

    }

运行例子, 调整target的值, 可见Scene视图中, cube以及绘制出来的局部坐标轴也相应地发生了变化。

LookAt()与LookRotation()的参数都相似,但前者是将游戏对象的z轴指向参数所表示的那个点,而后者是将游戏对象的z轴指向参数所表示的向量的方向;

static function Angle (a : Quaternion, b : Quaternion) : float

返回a和b两者之间的角度。

public class example : MonoBehaviour {

                           public Transform target;

void Update() {

                            float angle = Quaternion.Angle(transform.rotation, target.rotation);

                           }

}

Vector3.Angle

public static float Angle(Vector3 from, Vector3 to);

由from和to两者返回一个角度。形象的说,from和to的连线和它们一个指定轴向的夹角。

把脚本放到小立方体上面,当小立方体和球体之间的夹角小于5度时关门

public class example : MonoBehaviour {

                           public Transform target; //球体

                           void Update() {

                                    Vector3 targetDir = target.position - transform.position;

                                    Vector3 forward = transform.forward;

                                    float angle = Vector3.Angle(targetDir, forward);

                                    if (angle < 5.0F)

                                             print("close");

else

         print("open");

                       }

}

  1. 欧拉角

static function Euler (x : float, y : float, z : float) : Quaternion

返回一个旋转角度,绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度(像这样的顺序)。

public class example : MonoBehaviour {

                           public Quaternion rotation = Quaternion.Euler(0, 30, 0);

}

  1. 球形插值

static function Slerp (from : Quaternion, to : Quaternion, t : float) : Quaternion

球形插值,通过t值from向to之间插值。可以理解为速度,通常取值为0< t <= 1

public class example : MonoBehaviour {

                  public Transform from;

                  public Transform to;

                  public float speed = 0.1F;

                  void Update() {

//可以把 speed * Time.time 理解成速度 * 时间 等于角位移

                  transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, Time.time * speed);

                  }

}

四元数旋转有个重要的特性就是:到达终止方向的旋转角度为旋转方向

例如起始位置为(0,0,0),绕Y轴旋转200度到(0,200,0),物体会顺时针旋转160度而不是逆时针旋转200度。

首先在场景中创建三个cubefrom表示要转换之前的样子,to表示转换之后的样子,change表示转的效果。如下图所示:

其中fromchange 开始运行之前的transform是一样的。to transform如下图所示:

然后我们创建一个脚本Quat.cs,如下:

public class Quat : MonoBehaviour {

    public Transform from;

    public Transform to;

    private float rotSpeed = 5.0f;

    void Update () {

        if (Input.GetMouseButtonDown(0))

        {

            rotSpeed += 4;

            transform.rotation = Quaternion.Slerp(from.rotation, to.rotation, rotSpeed*Time.deltaTime);

        }

    }

}

我们把该脚本赋change,并且把fromto拖到相应的手槽里。然后运行时,我们点击鼠标左键,可以看到change 慢慢旋转成to的角度。如下所示:

点一次插入一个值,偏移一点点,直到和to的角度一样。

当枪管转动起来,子弹仍然沿着正确的朝向发射出去。

      Bullet_2 bullet = m_compPool.takeUnit<Bullet_2>();
      //发射时,将子弹的初始位置为枪口的当前位置
      bullet.m_transform.position = m_transform.position;
     //将子弹的初始化旋转设置为指向当前枪口前方
bullet.m_transform.rotation=Quaternion.LookRotation(m_transform.forward);

  1. 插值

在 a 和 b 之间插入 t,然后对结果进行标准化处理。参数 t 被限制在 [0, 1] 范围内。

该方法比 Slerp 快,但如果旋转相距很远,其视觉效果也更糟糕。

using UnityEngine;

using System.Collections;

public class ExampleClass : MonoBehaviour {

    public Transform from;

    public Transform to;

    public float speed = 0.1F;

    void Update() {

      transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, Time.time * speed);

    }

}

  1. 恒等式旋转

返回恒等式旋转(只读)。这个四元数对于“无旋转”:这个物体完全对齐于世界或父轴。

public class example : MonoBehaviour {

                  public void Awake() {

                           transform.rotation = Quaternion.identity;

                  }

}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值