一、什么是Transform?
场景中的每一个物体都有一个Transform,用于存储和操作对象的位置、旋转和缩放,存在层级关系(父级和子级)。
二、常用变量与属性(位置)
1.位置
position:世界坐标
localposition:相对坐标(父物体就是世界,相对于父物体的坐标)
private void OnGUI()
{
//世界坐标
GUILayout.Label(string.Format("Transform's position:{0}", transform.position));
//相对坐标
GUILayout.Label(string.Format("Transform's localPosition:{0}", transform.localPosition));
}
2.角度
enlerAnles,localEnlerAnles欧拉角;rotation,localRotation四元数旋转角度(自然数)。
private void OnGUI()
{
//相对世界的欧拉角
GUILayout.Label(string.Format("Transform's eulerAngles:{0}", transform.eulerAngles));
//相对父物体的欧拉角
GUILayout.Label(string.Format("Transform's localEulerAngles:{0}", transform.localEulerAngles));
//相对世界的rotation
GUILayout.Label(string.Format("Transform's rotation:{0}",
transform.rotation));
//相对父物体的rotation
GUILayout.Label(string.Format("Transform's localRotation:{0}", transform.localRotation));
//欧拉角转换成自然数方式
transform.rotation = Quaternion.EulerAngles(270, 0, 0);
}
3.缩放
localScale相对父级缩放比例;lossyScale相对世界缩放比例。
private void OnGUI()
{
//相对父级缩放
GUILayout.Label(string.Format("Transform's localScale:{0}", transform.localScale));
//相对世界的缩放
GUILayout.Label(string.Format("Transform's lossyScale:{0}", transform.lossyScale));
}
4.其他
right(向左),up(向上),forward(向前)方向向量。
private void OnGUI()
{
//向右
GUILayout.Label(string.Format("Transform's right:{0}", transform.right));
//向上
GUILayout.Label(string.Format("Transform's up:{0}", transform.up));
//向前
GUILayout.Label(string.Format("Transform's forward:{0}", transform.forward));
}
parent(父级),root(根物体),childCount(多少个子级)子父级相对。
private void OnGUI()
{
//向右
GUILayout.Label(string.Format("Transform's right:{0}", transform.parent.name));
//向上
GUILayout.Label(string.Format("Transform's up:{0}", transform.root.name));
//向前
GUILayout.Label(string.Format("Transform's forward:{0}", transform.childCount));
}
三、移动
1.直接修改位置
小技巧:优化,缓存和不缓存。
public Transform trans;
public int Count = 1000; //缓存次数
private long NoCache = 0; //不缓存
private long Cache = 0; //缓存
// Start is called before the first frame update
void Start()
{
trans = this.transform; //获得trans,能提高效率,缓存
Stopwatch sw = new Stopwatch();
sw.Start(); //启动Stopwatch
for (int i = 0; i < Count; i++) { //循环次数
Transform t = this.transform;
}
sw.Stop();
NoCache = sw.ElapsedTicks;
sw.Reset();
sw.Start();
for (int i = 0; i < Count; i++) {
Transform t = trans; //直接获取trans
}
sw.Stop();
Cache = sw.ElapsedTicks;
}
private void OnGUI()
{
//向右
GUILayout.Label(string.Format("Transform's NoCache:{0}", NoCache));
//向上
GUILayout.Label(string.Format("Transform's Cache:{0}", Cache));
}
移动
public Transform trans;
private bool moveToLeft = true; //控制左右移动
private float speed = 2;
// Start is called before the first frame update
void Start()
{
trans = this.transform; //获得trans,能提高效率,缓存
}
// Update is called once per frame
void Update()
{
Move();
// trans.position = new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), Random.Range(-3f, 3f)); //直接移动,随机移动,随机数-3*3
// trans.position = new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), Random.Range(-3f, 3f)); //直接移动,随机移动,随机数-3*3
}
private void Move()
{
if (trans.position.x <= -3 && moveToLeft) { //在x轴-3到3移动,向左移动为true
moveToLeft = false; //向右移动
} else if(trans.position.x >= 3 && !moveToLeft){
moveToLeft = true; //向左移动
}
trans.position += (moveToLeft?Vector3.left : Vector3.right) * Time.deltaTime * speed; //判断向左向右,后面的话是指每秒;如果向左移动,每秒钟向左移动两个单位。。。
}
2.Translate函数
1.1 依据自身坐标移动
private void Translate()
{
if (transform.position.x < -3 && moveToLeft)
{ //在x轴-3到3移动,向左移动为true
moveToLeft = false; //向右移动
}
else if (transform.position.x >= 3 && !moveToLeft)
{
moveToLeft = true; //向左移
}
transform.Translate((moveToLeft ? Vector3.left : Vector3.right) * Time.deltaTime * speed, Space.Self);
}
1.2 space可以控制是沿自身方向(space.Self)移动还是沿世界方向(space.World)移动。
下面这段代码是沿着世界向前移动。
public Transform trans;
void Start()
{
trans = this.transform;
}
void Update()
{
Translate(Space.World);
}
private void Translate(Space space) {
trans.Translate(Vector3.forward *Time.deltaTime *2, space);
}
四、旋转
1.直接修改欧拉角和旋转角
修改eulerAngles欧拉角和rotation定义旋转角度代码如下:
public Transform trans;
public float speed = 90;
private void Start() {
trans = this.transform;
}
private void Update()
{
// trans.eulerAngles = new Vector3(0, 0, 45); //在z轴旋转45°
trans.eulerAngles = new Vector3(0, 0, 45); //相对父级
trans.rotation = Quaternion.Euler(0,0,45); //
trans.localRotation = Quaternion.Euler(0, 0, 45); //相对父级
// trans.eulerAngles += Time.deltaTime * speed * Vector3.forward; //沿着z轴旋转
trans.rotation = Quaternion.Euler(trans.eulerAngles.x, trans.eulerAngles.y, trans.eulerAngles.z + Time.deltaTime *speed); //沿着z轴旋转
}
2. Rotate,RotateAround和LookAt函数
2.1 Rotate函数实现旋转功能跟修改欧拉角和旋转角进行旋转有一样的效果,只需要填写一个方向和旋转的速度。
private void Rotate() {
trans.Rotate(Vector3.forward * Time.deltaTime * speed); //跟修改欧拉角和旋转角进行旋转有一样的效果,只需要填写一个方向和旋转的速度
}
2.2 RotateAround函数实现sphere围绕cube旋转,代码如下:
public Transform target; //围绕的点
private void Rotate() {
trans.RotateAround(target.position, target.up, Time.deltaTime *speed); //围绕旋转的点、轴向、速度
}
2.3 LookAt函数,z轴看向,比如把sphere移动一下,cube也是一直始终看向sphere。
public Transform target; //围绕的点
private void LookAt() {
trans.LookAt(target);
}
3.利用right,up,forward改变方向
private void ChangeDir() {
Vector3 dir = target.position - trans.position; //trans指向target
trans.up = dir;
}
五、缩放
1.直接修改缩放比例
public Transform trans;
public float speed = 1;
public bool ZoomInt; //放大还是缩小
private void Start()
{
trans = this.transform;
}
private void Update()
{
Zoom();
}
public void Zoom() {
if (trans.localScale.x <= 0 && !ZoomInt) { //放大
ZoomInt = true;
} else if(trans.localScale.x <=3 && ZoomInt) //缩小
{
ZoomInt = false;
}
trans.localScale += (ZoomInt ? Vector3.right : Vector3.left) * Time.deltaTime*speed; //是否放大,left相当于-right
}
五、其他常用函数
1. TransformDirection和InverseTransformDirection
1.1 TransformDirection可以实现人物可以朝着摄像机的方向移动而不一定是世界坐标,把希望的方向转给trans,代码如下。
public Transform trans;
private void Start()
{
trans = this.transform;
}
private void Update()
{
Debug.DrawRay(trans.position, trans.TransformDirection(Camera.main.transform.forward) *10, Color.red); // Debug.DrawRay()画一根线,从trans的位置
}
1.2 InverseTransformDirection,处理镜像运动。
Debug.DrawRay(trans.position, trans.InverseTransformDirection(Camera.main.transform.forward) * 10, Color.yellow);
2. DetachChilder,Find,GetChild和IsChildOf
private Transform trans;
public Transform Child;
private void Start()
{
trans = this.transform;
}
private void Update()
{
}
private string _IsChild; //记录
private void OnGUI()
{
if (GUILayout.Button("Detch Children")) { //将当前transform下的子物体分离出来,取消他们的一个关系
trans.DetachChildren();
}
if (GUILayout.Button("Find Children")) //查找"Child"
{
trans.Find("Child").position = Vector3.one * 3;
}
if (GUILayout.Button("GetChildren")) //获得子物体的方式,是根据索引值来获取的
{
trans.GetChild(0).position = Vector3.one * 5;
}
if (GUILayout.Button("IsChildOf")) //检测当前transform是不是我们参数里填的transform的子物体
{
_IsChild = Child.IsChildOf(trans).ToString();
}
GUILayout.Label(_IsChild);
}