栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

Unity 四元数

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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度。

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

其中from和change 开始运行之前的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,并且把from和to拖到相应的手槽里。然后运行时,我们点击鼠标左键,可以看到change 慢慢旋转成to的角度。如下所示:

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

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

      Bullet_2 bullet = m_compPool.takeUnit();
      //发射时,将子弹的初始位置为枪口的当前位置
      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;

                  }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/905848.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号