Transform.Rotate详解
1.问题引出
2.代码说明
3.原理解释
4.小结
Transform.Rotate传入了一个欧拉角三元组(或者单独的三个float类型数据),以及一个标识符用于标记旋转的参考系是自身还是全局参考系:
比较令人迷惑的地方在于最后一个参数Space relativeTo = Space.Self | Space.World
官网为了说明这个问题,给了一份源码:
using UnityEngine;
// Transform.Rotate example
//
// Two cubes are created. One (red) is rendered using Space.Self. The
// other (green) uses Space.World. The rotation is controlled using xAngle,
// yAngle and zAngle. Over time, the cubes rotate differently.
public class ExampleScript : MonoBehaviour
{
public float xAngle, yAngle, zAngle;
public Material selfMat, worldMat;
private GameObject cube1, cube2;
void Awake()
{
cube1 = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube1.transform.position = new Vector3(0.75f, 0.0f, 0.0f);
cube1.GetComponent().material = selfMat;
cube1.name = "Self";
cube2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube2.transform.position = new Vector3(-0.75f, 0.0f, 0.0f);
cube2.GetComponent().material = worldMat;
cube2.name = "World";
}
void Update()
{
cube1.transform.Rotate(xAngle, yAngle, zAngle, Space.Self);
cube2.transform.Rotate(xAngle, yAngle, zAngle, Space.World);
}
}
经过看官网的源码,还是很疑惑,因为官网的最初的X,Y,Z轴的坐标系,自身坐标系和空间的坐标系是重合的
所以,旋转起来的效果也完全相同,个人将官网的代码修改之后并对初始对象进行旋转,使其X,Y,Z初始状态
下的坐标系与Scene的坐标系不重合,之后就能很容易地看出区别了:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Transform.Rotate example
//
// Two cubes are created. One (red) is rendered using Space.Self. The
// other (green) uses Space.World. The rotation is controlled using xAngle,
// yAngle and zAngle. Over time, the cubes rotate differently.
public class TransformRotateTest : MonoBehaviour
{
public float xAngle, yAngle, zAngle;
public Material selfMat, worldMat;
public GameObject cube1, cube2;
void Awake()
{
// cube1 = GameObject.CreatePrimitive(PrimitiveType.Cube);
// cube1.transform.position = new Vector3(0.75f, 0.0f, 0.0f);
cube1.GetComponent().material = selfMat;
cube1.name = "Self";
// cube2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
// cube2.transform.position = new Vector3(-0.75f, 0.0f, 0.0f);
cube2.GetComponent().material = worldMat;
cube2.name = "World";
}
void Update()
{
cube1.transform.Rotate(xAngle, yAngle, zAngle, Space.Self);
cube2.transform.Rotate(xAngle, yAngle, zAngle, Space.World);
}
}
然后在空间中创建两个状态一致的Cube(仅Material和Position不同),创建的流程:
1.首先创建一个Cube,然后旋转这个Cube,使其X,Y,Z周脱离空间的标准X,Y,Z轴
2.然后将这个Cube复制一份,然后平移得到另外一个Cube
3.给上面的两个Cube加入不同的材质(拖入Unity的框中)
4.设置转速均为(1,1,1)
5.将两个Cube拖入框中
6.运行查看结果
(创建一个空白的Cube用于挂载脚本)
图中红色Material材质渲染Self,蓝色渲染World,最终运行结果:
可以明显看到角度不同
因为两个物体最初都是有平行的局部坐标系(蓝色Cube由红色Cube直接复制平移得到,仅改变原点,不改变坐标系的平行性),但是这两个坐标系和Sence的全局坐标系是不平行的,所以在绕Self和World旋转的时候,行为也就不同了。
上图中的三角坐标系是局部坐标系(Self)
但是此时的空间坐标系(World)是这样的:
所以旋转的结果自然就不同了。
在使用Transform.Rotate的时候,根据是按照自己的坐标系旋转,还是按照整个空间的坐标系旋转,选择Self和World参数