一、基本概念

transform是Unity中用于控制对象位置、旋转和缩放的组件,而rotation则是transform中控制对象旋转的属性。在Unity中,rotation是一个四元数(Quaternion)变量,用于描述旋转的方向和强度。相比于欧拉角(Euler Angle)旋转,四元数旋转可以避免万向锁问题,也更加高效。

通过transform.rotation可以获取或设置物体的旋转,例如:

// 获取物体的旋转
Quaternion rotate = transform.rotation;
// 设置物体的旋转
Quaternion newRotate = Quaternion.Euler(0, 90, 0);
transform.rotation = newRotate;

二、旋转的表示方式

在Unity中,旋转可以通过四元数、欧拉角和矩阵三种方式来表示。其中四元数是最常用的方式,它可以通过Vector3类型的欧拉角转换而来。以下是三种表示方式的示例:

// 通过四元数表示旋转
Quaternion rotate = Quaternion.Euler(0, 90, 0);

// 通过欧拉角表示旋转
Vector3 euler = new Vector3(0, 90, 0);
Quaternion rotate = Quaternion.Euler(euler);

// 通过矩阵表示旋转
Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, rotate, Vector3.one);

三、旋转的插值

在游戏中,常常需要让物体在不同的时间点之间进行平滑的旋转,这就需要使用到旋转的插值。在Unity中,可以使用Quaternion.Slerp和Quaternion.Lerp两种方法进行插值,它们分别表示球形插值和线性插值。以下是它们的示例:

// 球形插值
Quaternion from = Quaternion.Euler(0, 0, 0);
Quaternion to = Quaternion.Euler(0, 90, 0);
float t = Mathf.PingPong(Time.time, 1);
Quaternion rotate = Quaternion.Slerp(from, to, t);

// 线性插值
Quaternion from = Quaternion.Euler(0, 0, 0);
Quaternion to = Quaternion.Euler(0, 90, 0);
float t = Mathf.PingPong(Time.time, 1);
Quaternion rotate = Quaternion.Lerp(from, to, t);

四、旋转的限制

在游戏开发中,常常需要限制物体的旋转,以保证游戏的正常运行和良好体验。例如,人物模型的头部不能旋转过度,否则会显得可笑。在Unity中,可以使用Mathf.Clamp和Mathf.ClampAngle两种方法对旋转进行限制,以下是它们的示例:

// 限制旋转在一定范围内
Quaternion rotate = Quaternion.Euler(0, 90, 0);
float x = Mathf.Clamp(rotate.x, -0.5f, 0.5f);
float y = Mathf.Clamp(rotate.y, -0.5f, 0.5f);
float z = Mathf.Clamp(rotate.z, -0.5f, 0.5f);
rotate = new Quaternion(x, y, z, rotate.w);

// 限制旋转角度在一定范围内
Quaternion rotate = Quaternion.Euler(0, 90, 0);
float y = Mathf.Clamp(rotate.eulerAngles.y, 0, 90);
rotate = Quaternion.Euler(0, y, 0);

五、旋转的与其它属性的关联

在Unity中,旋转往往与其它属性(例如位置、大小等)存在相关性。例如,当物体向左倾斜时,它的位置也会有所变化;当旋转角度大于360度时,它的大小也会随之发生改变。因此,对旋转的处理需要综合考虑这些相关性。以下是它们的示例:

// 物体向左倾斜时,位置也发生变化
Quaternion rotate = Quaternion.Euler(45, 0, 0);
Vector3 pos = new Vector3(-1, 0, 0);
transform.position = rotate * pos;

// 旋转角度大于360度时,缩放也发生变化
Quaternion rotate = Quaternion.Euler(0, 720, 0);
float scale = Mathf.Clamp01(rotate.eulerAngles.y / 360); // 缩放变量
transform.localScale = new Vector3(scale, scale, scale);