16.Unity重要组件和API-Transform位置和位移
16.1 知识点
Transform主要用来干嘛
Transform 主要用于游戏对象(GameObject)的位移、旋转、缩放、父子关系、坐标转换等相关操作。它是 Unity 提供的极其重要的类。
Vector3三维向量基础
Vector3 主要用来表示三维坐标系中的一个点或者一个向量,用于表示 3D 向量和点。Unity 内部使用该结构传递 3D 位置和方向。此外,它还包含用于执行常见向量操作的函数。除了下面列出的函数以外,也可以使用其他类操作向量和点。例如,对于旋转或变换向量和点来说,Quaternion 和 Matrix4x4 类也很有用。
Vector3的申明
- 无参构造后赋值:
Vector3 v1 = new Vector3();
v1.x = 10;
v1.y = 10;
v1.z = 10;
- 传xy坐标参数的构造,默认z是0:
Vector3 v2 = new Vector3(10, 10);
- 传xyz坐标参数的参数构造,一步到位:
Vector3 v3 = new Vector3(10, 10, 10);
- 结构体直接声明 Vector3 变量后赋值:
Vector3 v4;
v4.x = 10;
v4.y = 10;
v4.z = 10;
Vector的基本计算
// + - * / 加减乘除
Vector3 v11 = new Vector3(1, 1, 1);
Vector3 v12 = new Vector3(2, 2, 2);
print(v11 + v12); // (3.0, 3.0, 3.0)
print(v11 - v12); // (-1.0, -1.0, -1.0)
print(v11 * 10); // (10.0, 10.0, 10.0)
print(v12 / 2); // (1.0, 1.0, 1.0)
Vector3常用的向量供我们使用
print(Vector3.zero); // (0, 0, 0)
print(Vector3.right); // (1, 0, 0)
print(Vector3.left); // (-1, 0, 0)
print(Vector3.up); // (0, 1, 0)
print(Vector3.down); // (0, -1, 0)
print(Vector3.forward); // (0, 0, 1)
print(Vector3.back); // (0, 0, -1)
Vector3.Distance方法 返回向量之间的距离
// 返回 a 与 b 之间的距离。
print(Vector3.Distance(v11, v12)); // 1.732051
位置
Vector3.position变量 相对世界坐标系的坐标
// 世界空间中的变换位置。
print(this.transform.position);
// 通过 position 得到的位置是相对于世界坐标系的原点的位置。可能和面板上显示的是不一样的,因为如果对象有父子关系,并且父对象位置不在原点,那么和面板上肯定就是不一样的。
Vector3.localPosition变量 相对父对象的坐标
// 相对于父变换的变换位置。
print(this.transform.localPosition);
// 这两个坐标对于我们来说很重要。如果你想以面板坐标为准来进行位置设置,那一定是通过 localPosition 来进行设置的。
position和localPosition值相等的情况:
- 父对象的坐标就是世界坐标系原点(0, 0, 0)。
- 对象没有父对象。
注意:坐标的赋值不能直接改变 x,y,z,只能整体改变。
// 不能单独改变 x、y、z 某一个值
// this.transform.position.x = 10; // 报错
this.transform.position = new Vector3(10, 10, 10); // 赋值一个 Vector3 向量
this.transform.localPosition = Vector3.up * 10; // 只要是 Vector3 就可以
如果只想改坐标中 x 值,y 和 z 保持原有坐标一致,有两种方法:
- 直接赋值,y 和 z 的值放到新的 Vector3 上:
this.transform.position = new Vector3(19, this.transform.position.y, this.transform.position.z);
- 先取出 Vector3,再赋值:
// 虽然不能直接改 transform 的 xyz,但是 Vector3 是可以直接改 xyz 的,所以可以先取出来改 Vector3,再重新赋值
Vector3 vPos = this.transform.localPosition;
vPos.x = 10;
this.transform.localPosition = vPos;
Transform.朝向 得到对象当前的一个朝向
// 对象当前的各朝向
print(this.transform.forward); // 对象当前的面朝向
print(this.transform.up); // 对象当前的头顶朝向
print(this.transform.right); // 对象当前的右手边
位移
理解坐标系下的位移计算公式
- 路程 = 方向 * 速度 * 时间
- 因为位移每一帧都要动,所以放在 Update 里
手动计算position
// 想要变化的就是 position,修改 position 即可。
// 用当前的位置 + 移动的方向向量 * 每帧移动的距离(可以理解为速度) * 每帧时间,得出最终每帧所在的位置。
// this.transform.position = this.transform.position + this.transform.up * 1 * Time.deltaTime;
//可以使用 += -=
// 因为用的是 this.transform.forward,所以它始终会朝向相对于自己的面朝向去动。
// this.transform.position += this.transform.forward * 1 * Time.deltaTime;
// 因为用的是 Vector3.forward,所以它始终会朝向相对于世界坐标系的面朝向去动。
// this.transform.position += Vector3.forward * 1 * Time.deltaTime;
// 方向非常重要,因为它决定了你的前进方向。
Transform.Translate方法 位移
// 根据 translation 的方向和距离移动变换。
// 参数一:每帧位移多少,每帧位移 = 移动的方向向量 * 每帧移动的距离(可以理解为速度) * 每帧时间。
// 参数二:相对坐标系,默认不填的话,该参数是相对于自己坐标系的。
// 移动的方向向量:Vector3.forward,相对坐标系:Space.World
// 相对于世界坐标系的 Z 轴动,始终是朝世界坐标系的 Z 轴正方向移动。
// this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.World);
// 移动的方向向量:this.transform.forward,相对坐标系:Space.World
// 相对于世界坐标的自己的面朝向去动,始终朝自己的面朝向移动。
// this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.World);
// 移动的方向向量:Vector3.forward,相对坐标系:Space.Self
// 相对于自己的坐标系下的 Z 轴正方向移动,始终朝自己的面朝向移动。
// this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.Self);
// 移动的方向向量:this.transform.forward,相对坐标系:Space.Self
// 相对于自己的坐标系下的自己的面朝向向量移动(一般不会这样让物体移动,双重叠加了偏移)。
// this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.Self);
注意:一般使用 Translate 方法来进行位移。
总结
- Vector3:如何申明,提供的常用静态属性和一个计算距离的方法。
- 位置:相对于世界坐标系和相对于父对象这两个坐标的区别,不能够单独修改 xyz,只能一起统一改。
- 位移:自己如何计算来进行位移,API 是哪个方法来进行位移,使用时要注意。
16.2 知识点代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson16_必不可少Transform_位置和位移 : MonoBehaviour
{
void Start()
{
#region Transform主要用来干嘛?
//游戏对象(GameObject)位移、旋转、缩放、父子关系、坐标转换等相关操作都由它处理
//它是Unity提供的极其重要的类
#endregion
#region 知识点一 Vector3基础
//Vector3主要是用来表示三维坐标系中的 一个点 或者一个向量
//用于表示 3D 向量和点。
//Unity 内部使用该结构传递 3D 位置和方向。 此外,它还包含用于执行常见向量操作的函数。
//除了下面列出的函数以外,也可以使用其他类操作向量和点。 例如,对于旋转或变换向量和点来说,Quaternion 和 Matrix4x4 类也很有用。
//Vector3的申明
//无参构造 后赋值
Vector3 v1 = new Vector3();
v1.x = 10;
v1.y = 10;
v1.z = 10;
//传xy坐标参数的构造 默认z是0
Vector3 v2 = new Vector3(10, 10);
//传xyz坐标参数的参数构造 一步到位
Vector3 v3 = new Vector3(10, 10, 10);
//结构体直接声明Vector3变量 后赋值
Vector3 v4;
v4.x = 10;
v4.y = 10;
v4.z = 10;
//Vector的基本计算
// + - * / 加减乘除
Vector3 v11 = new Vector3(1, 1, 1);
Vector3 v12 = new Vector3(2, 2, 2);
print(v11 + v12);//(3.0, 3.0, 3.0)
print(v11 - v12);//(-1.0, -1.0, -1.0)
print(v11 * 10);//(10.0, 10.0, 10.0)
print(v12 / 2);//(1.0, 1.0, 1.0)
//Vector3常用的向量供我们使用
print(Vector3.zero);//000
print(Vector3.right);//100
print(Vector3.left);//-100
print(Vector3.up);//010
print(Vector3.down);//0-10
print(Vector3.forward);//001
print(Vector3.back);//00-1
//Distance方法 计算两个点之间的距离的方法
//返回 a 与 b 之间的距离。
print(Vector3.Distance(v11, v12));//1.732051
#endregion
#region 知识点二 位置
//position变量 相对世界坐标系的坐标
//世界空间中的变换位置。
print(this.transform.position);
//通过position得到的位置 是相对于 世界坐标系的 原点的位置
//可能和面板上显示的 是不一样的
//因为如果对象有父子关系 并且父对象位置 不在原点 那么 和面板上肯定就是不一样的
//localPosition变量 相对父对象的坐标
//相对于父变换的变换位置。
print(this.transform.localPosition);
//这两个坐标 对于我们来说 很重要 如果你想以面板坐标为准来进行位置设置
//那一定是通过localPosition来进行设置的
//position和localPosition值相等的情况
//1.父对象的坐标 就是世界坐标系原点0,0,0
//2.对象没有父对象
//注意:位置的赋值不能直接改变x,y,z 只能整体改变
//不能单独改 x y z某一个值
//this.transform.position.x = 10;//报错
this.transform.position = new Vector3(10, 10, 10);//赋值一个Vector3向量
this.transform.localPosition = Vector3.up * 10;//只要是Vector3就可以
//如果只想改坐标中x值 y和z保持原有坐标一致 有两种方法
//1.直接赋值 y和z的值放到新的Vector3上
this.transform.position = new Vector3(19, this.transform.position.y, this.transform.position.z);
//2.先取出Vector3 再赋值
//虽然不能直接改 transform的 xyz 但是 Vector3是可以直接改 xyz的
//所以可以先取出来改Vector3 再重新赋值
Vector3 vPos = this.transform.localPosition;
vPos.x = 10;
this.transform.localPosition = vPos;
//transform.朝向 得到对象当前的 一个朝向
//对象当前的各朝向
print(this.transform.forward);//对象当前的面朝向
print(this.transform.up);//对象当前的头顶朝向
print(this.transform.right);//对象当前的右手边
#endregion
}
void Update()
{
#region 知识点三 位移
//理解坐标系下的位移计算公式
//路程 = 方向 * 速度 * 时间
//因为位移每一帧都要动 所以放在Update里
//手动计算position
//想要变化的 就是 position 修改position即可
//用当前的位置 + 移动的方向向量*每帧移动的距离(可以理解为速度)*每帧时间 得出最终每帧所在的位置
//this.transform.position = this.transform.position + this.transform.up * 1 * Time.deltaTime;
//可以使用+= -=
//因为用的是 this.transform.forward 所以它始终会朝向相对于自己的面朝向去动
//this.transform.position += this.transform.forward * 1 * Time.deltaTime;
//因为用的是 Vector3.forward 所以它始终会朝向相对于世界坐标系的面朝向去动
//this.transform.position += Vector3.forward * 1 * Time.deltaTime;
//方向非常重要 因为 它决定了你的前进方向
//Translate方法
//根据 translation 的方向和距离移动变换。
//参数一:每帧位移多少 每帧位移=移动的方向向量*每帧移动的距离(可以理解为速度)*每帧时间
//参数二:相对坐标系 默认不填的话 该参数 是相对于自己坐标系的
//移动的方向向量:Vector3.forward 相对坐标系:Space.World
//相对于世界坐标系的 Z轴 动 始终是朝 世界坐标系 的 Z轴正方向移动
//this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.World);
//移动的方向向量:this.transform.forward 相对坐标系:Space.World
//相对于世界坐标的 自己的面朝向去动 始终朝自己的面朝向移动
//this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.World);
//移动的方向向量:Vector3.forward 相对坐标系:Space.Self
//相对于自己的坐标系 下的 Z轴正方向移动 始终朝自己的面朝向移动
//this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.Self);
//移动的方向向量:this.transform.forward 相对坐标系:Space.Self
//相对于自己的坐标系 下的 自己的面朝向向量移动 (一般不会这样让物体移动,双重叠加了偏移)
//this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.Self);
//注意:一般使用Translate方法来进行位移
#endregion
}
//总结
//Vector3:如何申明 提供的 常用静态属性 和一个 计算距离的方法
//位置:相对于世界坐标系 和 相对于父对象 这两个坐标的区别 不能够 单独修改 xyz 只能一起统一改
//位移:自己如何计算来进行位移 API是哪个方法 来进行位移 使用时 要注意
}
16.3 练习题
一个空对象上挂了一个脚本,这个脚本可以让游戏运行时,在场景中创建出一个n层由Cube构成的金字塔(提示:实例化预设体或者实例化自带几何体方法)
//决定层数
for (int i = 0; i < n; i++)
{
//每一层开始创建时 应该得到一个 初始的坐标
Vector3 pos = new Vector3(-0.5f * i, -1 * i, 0.5f * i);
//决定每层多少个立方体
for (int j = 0; j < (i + 1) * (i + 1); j++)
{
//实例化 立方体
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
//然后设置位置
//因为 是起始位置 + 偏移位置 所以 Y不用变
obj.transform.position = pos + new Vector3(j % (i + 1) * 1, 0, j / (i + 1) * -1);
}
}
这四个方法,哪些才能让对象朝自己的面朝向移动?为何?(可以画图说明)
this.transform.Translate(Vector3.forward, Space.World);
this.transform.Translate(Vector3.forward, Space.Self);
this.transform.Translate(this.transform.forward, Space.Self);
this.transform.Translate(this.transform.forward, Space.World);
//this.transform.Translate(Vector3.forward, Space.World); //始终是朝向世界坐标系的Z轴移动的
//this.transform.Translate(Vector3.forward, Space.Self); //始终是朝向自己的面朝向移动的
//this.transform.Translate(this.transform.forward, Space.Self); //你也不知道朝哪里动 XXXXX
//this.transform.Translate(this.transform.forward, Space.World);//始终是朝向自己的面朝向移动的
- 可以理解为 this.transform和Space.Self都会根据当前对象坐标系和世界坐标系的偏移差计算后,进行偏移,this.transform.Translate(this.transform.forward, Space.Self);叠加了两次偏移所以不知道朝哪里动
使用你之前创建的坦克预设体,让其可以朝自己的面朝向向前移动
预制体要注意面朝z轴正方向
//在Update内
//this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.Self);
this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.World);
16.4 练习题代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson16_练习题 : MonoBehaviour
{
public int n = 10;
void Start()
{
#region 练习题一
//1.一个空对象上挂了一个脚本,这个脚本可以让游戏运行时,
//在场景中创建出一个n层由Cube构成的金字塔(提示:实例化预设体或者实例化自带几何体方法)
//决定层数
for (int i = 0; i < n; i++)
{
//每一层开始创建时 应该得到一个 初始的坐标
Vector3 pos = new Vector3(-0.5f * i, -1 * i, 0.5f * i);
//决定每层多少个立方体
for (int j = 0; j < (i + 1) * (i + 1); j++)
{
//实例化 立方体
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
//然后设置位置
//因为 是起始位置 + 偏移位置 所以 Y不用变
obj.transform.position = pos + new Vector3(j % (i + 1) * 1, 0, j / (i + 1) * -1);
}
}
#endregion
#region 练习题二
//2.
//this.transform.Translate(Vector3.forward, Space.World);
//this.transform.Translate(Vector3.forward, Space.Self);
//this.transform.Translate(this.transform.forward, Space.Self);
//this.transform.Translate(this.transform.forward, Space.World);
//这四个方法,哪些才能让对象朝自己的面朝向移动?为何?(可以画图说明)
//this.transform.Translate(Vector3.forward, Space.World); //始终是朝向 世界坐标系的 Z轴移动的
//this.transform.Translate(Vector3.forward, Space.Self); //始终是朝向自己的面朝向移动的
//this.transform.Translate(this.transform.forward, Space.Self); //你也不知道朝哪里动 XXXXX
//this.transform.Translate(this.transform.forward, Space.World);//始终是朝向自己的面朝向移动的
#endregion
}
void Update()
{
#region 练习题三
//3.使用你之前创建的坦克预设体,让其可以朝自己的面朝向向前移动
//在Update内
//this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.Self);
this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.World);
#endregion
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com