Unity编程标准导引-3.3 Transform

每个游戏对象(GameObject),其存在于游戏世界,都有一个位置、朝向、大小等基本定位信息;其存于Hierarchy面板,也存在与其他GameObject的相对关系,如父子关系、兄弟关系。Unity中使用Transform来描述和操作这些属性。
  Transform的字面理解就是“变换”的意思,所有的GameObject,当其被创建完成之后,均自动创建了这样一个变换组件,你不需要手动创建这个组件,而且无法删除此组件。
接下来,我们将变换组件的主要属性和功能一一进行解释。

3.3.1、层次相关的属性和方法

层次面板

  • childCount:代表当前GameObject节点下方有几个子节点
  • hierarchyCount:代表在当前GameObject所处的相互关联的树状结构中,存在的层次数目。
      相互关联的树状结构指的是:以Hierarchy面板中的一个顶层GameObject作为根节点出发的一棵树。任何一个GameObject都会存在于一棵树中。
      可以预想的是,这个树状结构中的任意一个节点的hierarchyCount属性都是相同的。
  • hierarchyCapacity:代表当前所在的树的层次容量。就是这棵树最大可以容纳的节点数目,从整个树中的任意一个节点访问此属性,所获取的层次容量都是相同的。
      这个参数是自动增长的,即当GameObject发生层次变动时,如果当前树的容量不足,会自动扩容。
      可以推测出:树中所有节点所查询的结果实际来自最顶层节点的属性,而当层次所发生变动时,Unity内部只需要修改顶层节点的这个属性即可。
      需要注意的是,当频繁变化hierarchyCapacity时,是需要带来额外的内存消耗和性能消耗的,这与List类的内存扩容是一个道理。因此,应该为频繁增长的树的根节点在一开始就设置一个比较大的容量。
  • parent:代表当前节点的父节点,返回一个Transform对象。当此parent为null时,就代表自己已经是顶层节点,也即树状结构中的根节点了。
  • root:获得当前树状结构中的根节点。
  • DetachChildren():分离子节点,意思就是将当前节点下方的所有直接子节点都分离出去,让他们成为根节点。有n个子节点,将产生n棵新的树。
  • Find(string name):根据路径查找子节点,虽然这里的参数在文档上显示为name,但是它实际代表一个路径。它可以是"magazine/ammo"这种格式,即可以向着叶节点深度方向查询多个层次,找到目标Transform并返回。如果找不到返回空。
  • GetChild(int index):根据索引index,返回当前节点的直接子节点。
  • GetSiblingIndex():获得当前节点处于其父节点下的编号索引,即处于兄弟列表中的Index。
  • SetAsFirstSibling():设置当前节点为兄弟节点列表中的第一个节点。
  • SetAsLastSibling():设置当前节点为兄弟节点列表中的最后一个节点。
  • SetSiblingIndex(int index):将当前节点设置到其兄弟列表中的index位置。
  • SetParent(Transform parent, bool worldPositionStays):设置当前节点的父节点,如果worldPositionStays设置为true,则保持其世界坐标下的位置、旋转和缩放。这会相应地修改其局部坐标、旋转和缩放信息。(后续章节会涉及到世界和局部坐标的概念)

3.3.2、变换相关的属性和方法

  这里所说的变换,就是指所处的位置、旋转(朝向)、缩放(大小)等信息。
  Unity下的单位是米,比如你新建一个Cube,那么它默认的尺寸是1x1x1的尺寸,那么我们想要设置这个Cube到需要的尺寸,只要修改它的Trasform下的Scale三维向量参数即可,它代表了在1x1x1这个基础上所进行的缩放。
  那些从外部导入的三维模型对象,它本身就带有一个局部的坐标系,和这个三维对象相对此局部坐标系的尺寸和位置。若要修改它的尺寸,则是基于此对象在其导入的局部坐标系中的尺寸和位置为基础,进行相应的缩放。
  由于一棵树代表了很多个层次的存在,每个节点均有自己的缩放、旋转、位置等信息。而且子节点的变换状态会跟随父节点变换状态的变化而改变,因此Unity中存在局部坐标和全局坐标的概念。局部坐标是指其相对直接父节点的变换信息,而全局坐标是指当前节点叠加了所有父节点的累积变换之后的状态结果。
  接下来详细了解变换相关的属性和方法。

  • Vector3 localPosition:局部坐标系下的位置
  • Vector3 position:全局坐标系下的位置
  • Quaternion localRotation:局部坐标系下的旋转
  • Quaternion rotation:全局坐标系下的旋转
  • Vector3 localScale:局部坐标系下的缩放
  • Vector3 lossyScale:全局坐标系下的缩放
  • Vector3 localEulerAngles:局部坐标系下的欧拉角
  • Vector3 eulerAngles 全局坐标系下的欧拉角
  • Vector3 forward:全局坐标系下的前方矢量
  • Vector3 up:全局坐标系下的上方矢量
  • Vector3 right:全局坐标系下的右方矢量

通过以上属性看出,都每个变换属性都有局部和全局之分。位置和缩放比较容易理解。不过缩放有两种表现形式,一种是欧拉角,一种是四元数,实际上四元数也就是使用欧拉角在进行计算。对于这部分数学不熟悉的同学不必紧张,我们不需要详细了解四元数的原理,只要学会使用即可。后续的章节中我们会慢慢熟悉四元数的一些用法,而对于欧拉角,我们只要简单知道其概念即可:欧拉角是用相对Z、X、Y轴旋转一定的度数来表示旋转的一种方法,请记住它是按照先Z、再X、再Y这个顺序进行旋转的。
  Unity文档上讲到,如果你对于欧拉角不是很熟悉,就不要使用它,四元数可以满足你的要求了。而实际上我们对于简单一些旋转计算,使用欧拉角是更方便的,速度也更快,比如,我们只需要某个物体相对其父节点围绕X、Y、Z中的单一轴进行旋转,此时文档相对简单,我们可以使用欧拉角进行处理,稍微复杂一点的情况,后面的四元数章节在做解释。
  另外需要注意几点:
  1、Vector、Quaternion 都是结构体,通过localRotation、position等以上函数获取的结果都是存在一个结构体中的,此时的返回结果是存在单独开辟的新内存中的,因此对其直接修改不能影响其原有数值,我们必须以localRotation=Vector这种形式对其赋值,让其进行函数内进行实际赋值操作。
  2、Transform也是一个组件,尽管每个GameObject类中都有transform这个成员,但其内部实现依然是getComponent的函数调用,而这种函数调用是比较耗时的,考虑到频繁需要对Transform进行操作,因此,我们应该在脚本的初始化过程中获取一个Transform引用并保留下来,以便后续调用而避免频繁使用到getComponent。这也是上一节代码中我们这样做的目的。

本文为博主原创文章,欢迎转载。请保留博主链接http://blog.csdn.net/andrewfan

时间: 2024-08-06 02:50:08

Unity编程标准导引-3.3 Transform的相关文章

Unity编程标准导引-3.2 MonoBehavior 组件父类重构

本文为博主原创文章,欢迎转载.请保留博主链接:http://blog.csdn.net/andrewfan 3.2MonoBehavior 组件父类重构 为了让我们的组件类用起来更方便,我们将上一节的代码进行重构.改写成如下: using UnityEngine; using System.Collections; namespace Assets.AndrewBox.Comp { /// <summary> /// 初始化状态 /// </summary> public enum

【Unity编程】Unity中关于四元数的API详解

Unity中关于四元数的API详解 Quaternion类 Quaternion(四元数)用于计算Unity旋转.它们计算紧凑高效,不受万向节锁的困扰,并且可以很方便快速地进行球面插值. Unity内部使用四元数来表示所有的旋转. Quaternion是基于复数,并不容易直观地理解. 不过你几乎不需要访问或修改单个四元数参数(x,y,z,w); 大多数情况下,你只需要获取和使用现有的旋转(例如来自"Transform"),或者用四元数来构造新的旋转(例如,在两次旋转之间平滑插入). 大

【Unity编程】四元数(Quaternion)与欧拉角

欧拉旋转.四元数.矩阵旋转之间的差异 除了欧拉旋转以外,还有两种表示旋转的方式:矩阵旋转和四元数旋转.接下来我们比较它们的优缺点. 欧拉角 优点:三个角度组成,直观,容易理解. 优点:可以进行从一个方向到另一个方向旋转大于180度的角度. 弱点:死锁问题. 前面<[Unity编程]欧拉角与万向节死锁(图文版)>已经介绍过万向节死锁问题. 四元数 内部由四个数字(在Unity中称为x,y,z和w)组成,然而这些数字不表示角度或轴,并且通常不需要直接访问它们.除非你特别有兴趣深入了解四元数学,你只

【Unity编程】Unity动画系统(一)

Unity动画系统 Unity动画系统,也称为"Mecanim",提供了以下功能: 简单的工作流程,设置动画的所有元素,包括对象,角色和属性. 支持导入外部创建的动画片段和使用内置动画编辑器制作的动画片段. 人型动画重新定位,动画角色的运动控制可以被所有的角色模型共享,即角色的外观(SkinedMesh)和运动(Animator)是分离的,它们互相组合之后形成最终的动画. 用于编辑动画状态的的简化工作流程,即动画控制器. 方便预览动画片段,以及片段之间的插值过渡. 这使得动画师可以独立

【Unity编程】欧拉角与万向节死锁(图文版)

万向节死锁(Gimbal Lock)问题 上文中曾经说过,欧拉旋转的顺规和轴向定义,自然造就了"万向节死锁"问题.本文主要来探索它自然形成的原因. 陀螺仪 首先,我们来了解Gimbal 究竟是个什么玩意儿.下面来自维基百科中关于Gimbal的一段引述: 平衡环架(英语:Gimbal)为一具有枢纽的装置,使得一物体能以单一轴旋转.由彼此垂直的枢纽轴所组成的一组三只平衡环架,则可使架在最内的环架的物体维持旋转轴不变,而应用在船上的陀螺仪.罗盘.饮料杯架等用途上,而不受船体因波浪上下震动.船

unity编程——小玩具

今天做了一个萤火虫飞舞效果,这个问题类似于一道算法题:一个点想移动到平面上任意一点,但是自身有一个旋转角度限制,每一次旋转时,最大旋转角度是 maxRotateAngle,思维延时(即两次连续执行自身指令的间隔)是 float gap. 大致思路是: 建立了四个指令,分别是: Blink()—— 萤火虫屁股发光,是闪烁的......闪烁的... Move()——(默认使用 Vector2 curSpeed 作为移动增量) ComputeDir() —— 根据目标位置,计算当前运动方向,因为旋转角

UNIX环境高级编程---标准I/O库

前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压根不是一码事.Unix I/O也叫低级I/O,也叫Unbuffered I/O,是操作系统内核部分,也是系统调用:而C标准I/O函数相对也成Buffered I/O,高级I/O,一般是为了效率考虑对这些系统调用的封装.以前使用getchar()经常为输入完后的回车而出错.那是不理解标准I/O实现时的

系统编程--标准IO

1.流和FILE对象 对于国际字符集,一个字符可以由一个以上的字节来表示.标准I/O文件流可以用来操作单字节和多字节(宽,wide)字符集.一个流的方向(orientation)决定了字符是以单字节还是多字节的方式读取,当一个流被创建时,它没有方向.如一个多字节I/O函数(见<wchar.h>)用在了没有方向的流上,那么流的方向会设为面向宽字符的.如果一个字节I/O函数用在一个没有方向的流上,那么流的方向会设为面向字节的.只有两个函数可以在设置后改变这个方向.freopen函数(简单说明)将会

Unity——编程中常见问题(永不止续)

问题:`System.IO.File' does not contain a definition for `ReadAllBytes' 解决: 这是由于unity的build settings默认指定web player平台,而非standalone build. file->build settings->选中相应的平台->switch platform即可. 参考资料: http://answers.unity3d.com/questions/1019958/systemiofil