Unity Transform 组件介绍
Transform 作为最重要,也是唯一一个GameObjcet物体必须具备的组件(2023.1之后在一些特定流工作流里可以创建没有Transform的对象,常规开发目前不需要,RectTransform 是 Transform 的子类,用于 UI 系统,它除了继承位置、旋转、缩放外,还增加了锚点、轴心点、尺寸等概念。UI 元素必须使用 RectTransform),中文翻译为“变换”,它用来控制GameObjcet的位置、旋转、缩放,作为本专栏第一个介绍的。官方手册链接官方手册链接,点击跳转
一、Transform 组件概念
1. 基础定义
- 本质:存储 GameObject 的位置(Position)、旋转(Rotation)、缩放(Scale)和父子关系状态
- 必备性:所有 GameObject 必须包含 Transform 组件,无法移除或创建无 Transform 的 GameObject
- 坐标系:
- 世界空间:无父物体时使用
- 局部空间:相对于父物体的坐标系
2. 属性详解
属性 | 数据类型 | 描述 | 默认值 |
---|---|---|---|
Position | Vector3 | X/Y/Z坐标位置 | (0,0,0) |
Rotation | Quaternion (常用欧拉角 Vector3 表示) | Rotation 属性底层使用 Quaternion 存储,但通常通过 eulerAngles (Vector3) 属性以欧拉角(度)的形式进行设置和读取 | (0,0,0) |
Scale | Vector3 | 沿X/Y/Z轴的缩放比例 | (1,1,1) |
Scale 特殊说明:值"1"表示原始大小(导入时的尺寸)
二、编辑 Transform 的三种方式
1. 场景视图(Scene View)操作
- 轴向标识:
- X轴:红色
- Y轴:绿色
- Z轴:蓝色
- 操作技巧:
- 单轴操作:沿特定轴拖动
- 平面锁定:点击Gizmo中心的彩色方块(如蓝色方块锁定Z轴)
- 轴向选择:点击后变为黄色表示选中
2. 检视窗口(Inspector)操作
- 精确输入:直接在数值字段输入
- 快速调整:点击字段后上下拖动鼠标
- 组件位置:位于GameObject检视窗口顶部
3. 脚本控制
// 位置控制
transform.position = new Vector3(1, 2, 3);
transform.Translate(Vector3.forward * Time.deltaTime);
// 旋转控制
transform.eulerAngles = new Vector3(0, 45, 0);
transform.Rotate(Vector3.up * 90 * Time.deltaTime);
// 缩放控制
transform.localScale = new Vector3(2, 2, 2);
三、父子关系与层级系统
1. 父子关系本质
- 继承规则:- 继承规则:(子物体在Hierarchy窗口中缩进显示)
变换类型 | 继承公式 | 数学表示 | 说明 |
---|---|---|---|
位置继承 | 子物体世界位置 = 父物体世界位置 + 父物体旋转后的局部位置 | ChildWorldPos = ParentWorldPos + ParentRotation * ChildLocalPos |
• 父物体的旋转会影响子物体的局部位置方向 • 局部位置是相对于父物体轴心点的偏移 |
旋转继承 | 子物体世界旋转 = 父物体世界旋转 × 子物体局部旋转 | ChildWorldRot = ParentWorldRot * ChildLocalRot |
• 使用四元数乘法(顺序:父×子) • 局部旋转是相对于父物体坐标系的旋转 |
缩放继承 | 子物体世界缩放 = 父物体世界缩放 × 子物体局部缩放 | ChildWorldScale = ParentWorldScale ⊗ ChildLocalScale |
• ⊗ 表示分量乘法(xx, yy, z*z) • 父物体缩放影响所有子物体的视觉尺寸 |
- 创建方法:在Hierarchy窗口中将GameObject拖到另一个上
- 层级限制:
- 一个GameObject只能有一个父物体
- 可以有多个子物体
- 无父物体的称为根物体(Root GameObject)
2. 坐标系转换
属性 | 描述 | 示例 |
---|---|---|
localPosition | 相对于父物体的位置 | (0,1,0) |
position | 世界坐标系位置 | (5,3,2) |
lossyScale | 世界空间中的最终缩放(累积所有父级缩放,只读,可能无法精确分解) | (2,2,2) |
// 世界坐标转局部坐标
Vector3 localPos = transform.InverseTransformPoint(worldPos);
// 局部坐标转世界坐标
Vector3 worldPos = transform.TransformPoint(localPos);
3. 父子关系实践
- 设置技巧:
// 创建父子关系 child.transform.SetParent(parentTransform); // 解除父子关系 child.transform.SetParent(null); // 保持世界位置不变 child.transform.SetParent(parentTransform, true);
四、缩放(Scale)深度解析
1. 缩放影响因素
2. 缩放与物理系统
- 物理假设:1 Unity单位 = 1米
- 缩放问题:
- 过大物体会"慢动作"下落(物理正确但视觉异常)
- 非均匀缩放导致碰撞体变形
3. 缩放最佳实践
- 建模阶段:
- 在3D软件中保持真实比例
- 避免在Unity中调整Transform的Scale值
- 导入设置:
- 在Import Settings中调整Mesh Scale Factor
- 保持最终比例为1:1:1
五、非均匀缩放
1. 基本概念
- 非均匀缩放:X/Y/Z缩放值不同(如(2,4,2))
- 均匀缩放:X/Y/Z缩放值相同(如(3,3,3))
2. 问题与限制
问题类型 | 具体表现 | 影响组件 |
---|---|---|
组件支持 | 圆形组件保持圆形 | Sphere Collider Capsule Collider Light Audio Source |
视觉变形 | 子物体旋转后扭曲 | 所有渲染组件 |
碰撞错位 | 碰撞体与网格不匹配 | Box Collider |
缩放更新 | 分离时突然变形 | 所有子物体 |
3. 解决方案
- 避免使用:尽量保持等比缩放
- 碰撞体补偿:
// 计算实际碰撞体尺寸 Vector3 actualSize = Vector3.Scale(collider.size, transform.lossyScale);
- 层级隔离:对需要非均匀缩放的对象单独分组
六、Transform API 参考手册
1. 核心属性
// 方向向量
Vector3 forward = transform.forward; // 物体前方
Vector3 up = transform.up; // 物体上方
Vector3 right = transform.right; // 物体右侧
// 层级关系
Transform parent = transform.parent; // 父物体
int childCount = transform.childCount; // 子物体数量
Transform firstChild = transform.GetChild(0); // 获取子物体
2. 实用方法
// 朝向目标
transform.LookAt(targetTransform);
// 查找子物体
Transform child = transform.Find("Arm/Hand");
// 索引管理
int index = transform.GetSiblingIndex();
transform.SetAsFirstSibling();
3. 高级操作
// 原子操作(避免多次计算)
transform.SetPositionAndRotation(newPos, newRot);
// 方向转换
Vector3 worldDir = transform.TransformDirection(localDir);
Vector3 localDir = transform.InverseTransformDirection(worldDir);
七、使用技巧
1. 性能优化
// 缓存Transform引用
private Transform _transform;
void Start()
{
_transform = transform;
}
void Update()
{
// 使用缓存引用
_transform.Rotate(Vector3.up, 30 * Time.deltaTime);
}
2. 场景设计
- 空物体锚点:创建空GameObject作为位置参考点
- 层级分组:
3. 调试技巧
// 绘制坐标轴
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, transform.position + transform.right);
Gizmos.color = Color.green;
Gizmos.DrawLine(transform.position, transform.position + transform.up);
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, transform.position + transform.forward);
}
八、常见问题解决方案
子物体位置异常
- 检查父物体缩放值
- 确认使用localPosition而非position
旋转抖动问题
- 使用Quaternion代替EulerAngles
- 避免万向节死锁
物理模拟异常
- 检查物体缩放比例
- 确保碰撞体未变形