Transform API

思考并回答以下问题:

Transform组件是Unity中最常用的组件,因为每个GameObject都会有Transform组件。物体最基本的位置、旋转、缩放都是由这个组件提供的。物体的父子关系也是由这个组件提供的。

Transform组件的文档位于:https://docs.unity3d.com/ScriptReference/Transform.html

如何修改物体的位置/旋转/缩放?

要想知道如何修改物体的位置/旋转/缩放,首先要知道如何获取,这时就要用到transform组件。

我们之前知道获取物体上的组件组要通过GetComponent获取,那么获取Transform组件就是GetComponent()。

其实在Unity中还有更简单的写法,就是直接使用transform。比如下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;

public class Test : MonoBehaviour
{
private GameObject other;

void Start ()
{
Debug.Log(transform.position); // 获取脚本所在物体的位置
Debug.Log(other.transform.position); // 获取其他物体的位置
}
}

在脚本中可以直接使用transform成员,获得当前脚本所在物体的Transform组件。

对于其他物体,可以直接通过gameObject.transform来获取这一物体的transform组件。

世界坐标位置:position
世界坐标旋转:rotation
自身缩放(缩放不区分世界或本地坐标系):localScale
本地坐标位置(相对于父物体,即Inspector中看到的position):localPosition
本地坐标旋转:localRotation

上面提到的两个旋转,类型都是Quaternion(四元数),此外还有两种分别是eulerAngles和localEulerAngles分别代表世界坐标欧拉角和本地坐标欧拉角(Vector3类型)。

什么是四元数和欧拉角?

四元数和欧拉角是两种表示旋转的表示方法。欧拉角比较直观,使用三维向量分别代表三个轴的旋转,但是存在万向锁的问题,所以引入了四元数的表示方法。Inspector面板中显示的旋转是欧拉角。后面也会详细解释。
获取这些属性后,如何修改呢?
除了rotation和localRotation的类型是Quaterniion,上述提到的其他属性,类型都是Vector3。

修改Transform组件中的属性例如:

1
transform.position = new Vector3(0, 10, 0);

一定要注意Vector3类型在创建的时候,也需要通过new关键字来创建。

Vector3类型

Vector3是三维向量,分别用x、y、z三个float值来代表在x、y、z轴上的值。
完整文档请见:https://docs.unity3d.com/ScriptReference/Vector3.html

如何修改物体的父子关系?

修改物体的父子关系也是非常常见的一种操作。比如我们动态生成一个盒子,需要跟随一辆货车一起移动,最简单的办法就是将盒子变成货车的子物体。

设置物体的父物体是通过Transform中下面这个API:

1
2
public void SetParent(Transform p);
public void SetParent(Transform parent, bool worldPositionStays);

注意传入的参数时Transform类型,不是GameObject类型。
默认情况下,使用第一种SetParent会保留物体的世界坐标、旋转、缩放,和在Hierarchy中直接调整父子关系类似。
但是某些情况下我们想让物体的位置、旋转、缩放变成相对于父物体的位置、旋转、缩放。这时候就需要用到第二种形式,并且第二个参数worldPositionStays传入false。

调整父子关系,保留世界坐标

如上图中就是保留世界位置,Cube2的世界坐标位置没有变,但是相对于父物体的位置会发生变化。

如果使用下面的代码改变Cube2的父子关系,我们来看一下:

1
2
3
4
5
6
7
8
9
10
11
using UnityEngine;

public class Test : MonoBehaviour
{
public Transform cube1;

void Start ()
{
transform.SetParent(cube1, false);
}
}

不保留世界位置的SetParent.gif

执行的效果如上图,cube2的位置发生了变化。这是为什么呢?因为Cube2在设置父物体时不保留世界坐标的位置,原来世界坐标(3,0,0)会变成相对父物体的坐标,而父物体的位置是(1,0,0),实际上Cube2最终的世界坐标会变成(4,0,0),所以位置发生了变化。大多数需要worldPositionStays为false的情况都是在动态生成UI的时候。

如何获取物体的所有子物体?

可以通过foreach循环遍历一个物体的所有子Transform组件。

1
2
3
4
5
6
7
8
9
public Transform cube1;

void Start ()
{
foreach (Transform tran in cube1)
{
Debug.Log(tran.gameObject.name);
}
}

当然也可以通过for循环来获取一个物体的所有子物体:

1
2
3
4
5
6
7
8
9
public Transform cube1;

void Start ()
{
for (int i = 0; i ‹ cube1.childCount; i++)
{
Debug.Log(cube1.GetChild(i).name);
}
}

childCount可以获取子物体的个数,GetChild(index)方法可以获取第index个子物体。

如何查找子物体?

有些情况我们需要在一个物体的子物体中按名称查找物体,这时候可以用到Transform组件中的Find方法。

public Transform Find(string n);
查找时也可以使用/类似路径来使用。比如下面特别注意1中的例子。

特别注意1
Transform的Find方法只能查找第一层的子物体。

比如这个图中查找GameObject的子物体,就只能查找sphere1和sphere2,无法找到sphere3,如果想找sphere3,就必须使用’sphere2/sphere3’作为参数
比如这个图中查找GameObject的子物体,就只能查找sphere1和sphere2,无法找到sphere3,如果想找sphere3,就必须使用’sphere2/sphere3’作为参数

特别注意2
这个方法可以找到active是false的物体。(与GameObject.Find的区别)

如何旋转一个物体?

旋转物体通常是新手的一个难点。

最开始我们需求最多的可能是物体自身旋转x度。
这时候需要用到的API是:

1
public void Rotate(Vector3 eulers, Space relativeTo = Space.Self);

这个API的第一个参数是在x、y、z轴上旋转的度数。比如只沿y轴旋转30度,需要传入new Vector3(0, 30, 0)。
第二个参数是相对的坐标空间。枚举中有两个值可以选择:Space.World和Space.Self。

选择Space.World时,物体是沿着世界坐标轴的方向进行旋转。绿色的线是沿Y轴旋转。

SpaceWorld.gif

选择Space.Self时,物体是沿着自身坐标轴的方向进行旋转。绿色的线是沿Y轴旋转。

SpaceSelf.gif

还有一个API是RotateAround,这个旋转可以让物体围绕一个物体旋转,比如地球绕太阳公转。

1
public void RotateAround(Vector3 point, Vector3 axis, float angle);

在世界坐标系统,围绕一个点point的axis轴旋转angle度。

比如下面的例子:

1
2
3
4
5
6
7
8
9
10
11
using UnityEngine;

public class Test : MonoBehaviour
{
public Transform sun;

void Update()
{
transform.RotateAround(sun.position, sun.up, 1);
}
}

围绕太阳的位置的up方向,也就是物体本地坐标轴绿色轴的方向,每帧旋转1度(这种方式实际不太合理,我们明天会仔细讲)。

地球围绕太阳旋转.gif

官方

Transform
class in UnityEngine/Inherits from:Component/Implemented in:UnityEngine.CoreModuleLeave feedback
SWITCH TO MANUAL
Description
Position, rotation and scale of an object.

Every object in a Scene has a Transform. It’s used to store and manipulate the position, rotation and scale of the object. Every Transform can have a parent, which allows you to apply position, rotation and scale hierarchically. This is the hierarchy seen in the Hierarchy pane. They also support enumerators so you can loop through children using:

using UnityEngine;

public class Example : MonoBehaviour
{
// Moves all transform children 10 units upwards!
void Start()
{
foreach (Transform child in transform)
{
child.position += Vector3.up * 10.0f;
}
}
}
See Also: The component reference, Physics class.

Properties
childCount The number of children the parent Transform has.
eulerAngles The rotation as Euler angles in degrees.
forward The blue axis of the transform in world space.
hasChanged Has the transform changed since the last time the flag was set to ‘false’?
hierarchyCapacity The transform capacity of the transform’s hierarchy data structure.
hierarchyCount The number of transforms in the transform’s hierarchy data structure.
localEulerAngles The rotation as Euler angles in degrees relative to the parent transform’s rotation.
localPosition Position of the transform relative to the parent transform.
localRotation The rotation of the transform relative to the transform rotation of the parent.
localScale The scale of the transform relative to the parent.
localToWorldMatrix Matrix that transforms a point from local space into world space (Read Only).
lossyScale The global scale of the object (Read Only).
parent The parent of the transform.
position The world space position of the Transform.
right The red axis of the transform in world space.
root Returns the topmost transform in the hierarchy.
rotation A quaternion that stores the rotation of the Transform in world space.
up The green axis of the transform in world space.
worldToLocalMatrix Matrix that transforms a point from world space into local space (Read Only).
Public Methods
DetachChildren Unparents all children.
Find Finds a child by n and returns it.
GetChild Returns a transform child by index.
GetSiblingIndex Gets the sibling index.
InverseTransformDirection Transforms a direction from world space to local space. The opposite of Transform.TransformDirection.
InverseTransformPoint Transforms position from world space to local space.
InverseTransformVector Transforms a vector from world space to local space. The opposite of Transform.TransformVector.
IsChildOf Is this transform a child of parent?
LookAt Rotates the transform so the forward vector points at /target/‘s current position.
Rotate Use Transform.Rotate to rotate GameObjects in a variety of ways. The rotation is often provided as a Euler angle and not a Quaternion.
RotateAround Rotates the transform about axis passing through point in world coordinates by angle degrees.
SetAsFirstSibling Move the transform to the start of the local transform list.
SetAsLastSibling Move the transform to the end of the local transform list.
SetParent Set the parent of the transform.
SetPositionAndRotation Sets the world space position and rotation of the Transform component.
SetSiblingIndex Sets the sibling index.
TransformDirection Transforms direction from local space to world space.
TransformPoint Transforms position from local space to world space.
TransformVector Transforms vector from local space to world space.
Translate Moves the transform in the direction and distance of translation.
Inherited Members
Properties
gameObject The game object this component is attached to. A component is always attached to a game object.
tag The tag of this game object.
transform The Transform attached to this GameObject.
hideFlags Should the object be hidden, saved with the Scene or modifiable by the user?
name The name of the object.
Public Methods
BroadcastMessage Calls the method named methodName on every MonoBehaviour in this game object or any of its children.
CompareTag Is this game object tagged with tag ?
GetComponent Returns the component of Type type if the game object has one attached, null if it doesn’t.
GetComponentInChildren Returns the component of Type type in the GameObject or any of its children using depth first search.
GetComponentInParent Returns the component of Type type in the GameObject or any of its parents.
GetComponents Returns all components of Type type in the GameObject.
GetComponentsInChildren Returns all components of Type type in the GameObject or any of its children.
GetComponentsInParent Returns all components of Type type in the GameObject or any of its parents.
SendMessage Calls the method named methodName on every MonoBehaviour in this game object.
SendMessageUpwards Calls the method named methodName on every MonoBehaviour in this game object and on every ancestor of the behaviour.
TryGetComponent Gets the component of the specified type, if it exists.
GetInstanceID Returns the instance id of the object.
ToString Returns the name of the GameObject.
Static Methods
Destroy Removes a gameobject, component or asset.
DestroyImmediate Destroys the object obj immediately. You are strongly recommended to use Destroy instead.
DontDestroyOnLoad Do not destroy the target Object when loading a new Scene.
FindObjectOfType Returns the first active loaded object of Type type.
FindObjectsOfType Returns a list of all active loaded objects of Type type.
Instantiate Clones the object original and returns the clone.
Operators
bool Does the object exist?
operator != Compares if two objects refer to a different object.
operator == Compares two object references to see if they refer to the same object.

0%