Unity_Transform组件_006

来源:互联网 发布:自适应网址导航源码 编辑:程序博客网 时间:2024/05/18 21:10

()任何游戏对象在创建的时候都会附带Transform组件,用于储存并操控物体的位置、旋转和缩放。
并且该组件是无法删除的。
Transform面板一共包含3个属性:
Position:位置
Rotation:旋转
Scale:(缩放)
可修改对象的位置、旋转方式、缩放数值


位置

  • position
    transform.position是一个可读可写的属性。transform.position是相对于世界坐标系来展示坐标的
    参考代码:
void Start () {        //在控制台上打印绑定此脚本游戏对象的位置信息        Debug.Log(transform.position);        //对绑定此脚本的游戏对象重新设置位置        transform.position = new Vector3(2,2,2);        Debug.Log(transform.position);    }
  • localPosition
    transform.localPosition是一个可读可写的属性。transform.localPosition是利用局部坐标系来展示坐标的,即把父节点作为原点,自身位置就是相对于父节点的在三个轴向上的距离

    两者的区别
    在场景中创建一个Cube1,并创建Cube1的子物体Cube2.设置Cube1的坐标为(5,6,7),同时设置Cube2为(0,0,2).
    将脚本挂载到Cube2的游戏物体上,代码如下:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class TransformDemo : MonoBehaviour {    // Use this for initialization    void Start () {        //在控制台上打印绑定此脚本游戏对象的位置信息        //在控制台上打印的内容是(5.0,6.0,9.0) 表示的是Cube2在世界坐标系下表示的位置  参考的坐标是是世界的原点        Debug.Log(transform.position);        //在控制台上打印的内容是(0.0,0.0,2.0) 表示的是Cube2在局部坐标系下表示的位置  参考的坐标系是Cube1        Debug.Log(transform.localPosition);    }}

旋转

  • 欧拉角
    优点:
    很容易理解,形象直观;
    表示更方便,只需要3个值(分别对应x、y、z轴的旋转角度);但按我的理解,它还是转换到了3个3*3的矩阵做变换,效率不如四元数;

    缺点:
    之前提到过这种方法是要按照一个固定的坐标轴的顺序旋转的,因此不同的顺序会造成不同的结果;
    会造成万向节锁(Gimbal Lock)的现象。这种现象的发生就是由于上述固定坐标轴旋转顺序造成的。理论上,欧拉旋转可以靠这种顺序让一个物体指到任何一个想要的方向,但如果在旋转中不幸让某些坐标轴重合了就会发生万向节锁,这时就会丢失一个方向上的旋转能力,也就是说在这种状态下我们无论怎么旋转(当然还是要原先的顺序)都不可能得到某些想要的旋转效果,除非我们打破原先的旋转顺序或者同时旋转3个坐标轴。这里有个视频可以直观的理解下;
    由于万向节锁的存在,欧拉旋转无法实现球面平滑插值;

    欧拉旋转是怎么运作的
    在Unity里,欧拉旋转的旋转顺序是Z、X、Y,这在相关的API文档中都有说明,例如Transform.Rotate。其实文档中说得不是非常详细,还有一个细节我们需要明白。如果你仔细想想,就会发现有一个非常重要的东西我们没有说明白,那就是旋转时使用的坐标系。给定一个旋转顺序(例如这里的Z、X、Y),以及它们对应的旋转角度(α,β,r),有两种坐标系可以选择:

    绕坐标系E下的Z轴旋转α,绕坐标系E下的Y轴旋转β,绕坐标系E下的X轴旋转r,即进行一次旋转时不一起旋转当前坐标系;
    绕坐标系E下的Z轴旋转α,绕坐标系E在绕Z轴旋转α后的新坐标系E’下的Y轴旋转β,绕坐标系E’在绕Y轴旋转β后的新坐标系E”下的X轴旋转r, 即在旋转时,把坐标系一起转动;

    很容易知道,这两种选择的结果是不一样的。但如果把它们的旋转顺序颠倒一下,其实结果就会一样。说得明白点,在第一种情况下、按ZXY顺序旋转和在第二种情况下、按YXZ顺序旋转是一样的。证明方法可以看下这篇文章。而Unity文档中说明的旋转顺序指的是在第一种情况下的顺序。

using System.Collections;using System.Collections.Generic;using UnityEngine;public class TransformDemo : MonoBehaviour {    // Use this for initialization    void Start () {        //第一种情况        //transform.Rotate(new Vector3(45, 30, 90));        //第二种情况分步骤做效果是一样的        transform.Rotate(new Vector3(0, 30, 0));        transform.Rotate(new Vector3(45, 0, 0));        transform.Rotate(new Vector3(0, 0, 90));    }}

如图:
第一种情况下的运行结果
这里写图片描述
第二种情况下的运行结果
这里写图片描述

  • 四元数
    优点:
    可以避免万向节锁现象;
    只需要一个4维的四元数就可以执行绕任意过原点的向量的旋转,方便快捷,在某些实现下比旋转矩阵效率更高;
    可以提供平滑插值;
    缺点:
    比欧拉旋转稍微复杂了一点点,因为多了一个维度;
    理解更困难,不直观;

四元数的创建

在了解了上述知识后,我们就不需要那么惧怕四元数了,实际上它和矩阵类似,不同的只是它的表示方式以及运算方式。那么在Unity里如何利用四元数进行旋转呢?Unity里提供了非常多的方式来创建一个四元数。例如Quaternion.AngleAxis(float angle, Vector3 axis),它可以返回一个绕轴线axis旋转angle角度的四元数变换。我们可以一个Vector3和它进行左乘,就将得到旋转后的Vector3。在Unity里只需要用一个“ * ”操作符就可以进行四元数对向量的变换操作,相当于我们上述讲到的p′=qpq−1操作。如果我们想要进行多个旋转变换,只需要左乘其他四元数变换即可。例如下面这样:

Vector3 newVector = Quaternion.AngleAxis(90, Vector3.up) * Quaternion.LookRotation(someDirection) * someVector;  

尽管欧拉角更容易我们理解,但四元数比欧拉角要强大很多。Unity提供了这两种方式供我们选择,我们可以选择最合适的变换。
例如,如果我们需要对旋转进行插值,我们可以首先使用Quaternion.eulerAngles来得到欧拉角度,然后使用Mathf.Clamp对其进行插值运算。
最后更新Quaternion.eulerAngles或者使用Quaternion.Euler(yourAngles)来创建一个新的四元数。

又例如,如果你想要组合旋转,比如让人物的脑袋向下看或者旋转身体,两种方法其实都可以,但一旦这些旋转不是以世界坐标轴为旋转轴,比如人物扭动脖子向下看等,那么四元数是一个更合适的选择。Unity还提供了transform.forward, transform.right and transform.up 这些非常有用的轴,这些轴可以和Quaternion.AngleAxis组合起来,来创建非常有用的旋转组合。例如,下面的代码让物体执行低头的动作:

transform.rotation = Quaternion.AngleAxis(degrees, transform.right) * transform.rotation;

缩放

  • localScale缩放(可读可写)
  • lossyScale全局缩放(只读属性)
//通过这种方式得到的缩放比例是参照父物体计算出来的,也就是说把父物体的的缩放作为标准。也可以通过游戏对象在三个轴上的实际尺寸/父物体对应的三个轴向上的尺寸得到的Debug.Log(transform.localScale);//表示的是游戏对象实际的缩放尺寸Debug.Log(transform.lossyScale);

【注】部分参考于此博客http://blog.csdn.net/candycat1992/article/details/41254799

原创粉丝点击