一些事实
1、假设有这样的层级结构:

那么 Cube4.rotation = Cube.localRotation * Cube1.localRotation * Cube2.localRotation * Cube3.localRotation * Cube4.localRotation。并且四元数乘法是从右往左依次应用,四元数乘法有结合律没有交换律,所以不能交换顺序。也就是说相当于把 Cube4 在无父物体无旋转的情况下,依次应用 Cube4-Cube 的 localRotation。
2、我用的 2021 版本的 Unity 进行测试,在建模软件中将坐标轴进行旋转,但导入 Unity 之后,将旋转归零,坐标轴依然与世界坐标轴保持一致。所以物体在无父物体无旋转的情况下,模型坐标轴也就是世界坐标轴。
准备工作
建三个 Cube,并设置好父子关系,先把三个物体的旋转都归零。


让物体绕自己的某一个轴旋转
代码如下:
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public Transform childCube1;
public Transform childCube2;
void Update()
{
Quaternion rotU = Quaternion.AngleAxis(100 * Time.deltaTime, Vector3.up);
childCube1.transform.rotation = childCube1.transform.rotation * rotU;
childCube2.transform.localRotation = childCube2.transform.localRotation * rotU;
}
}
还是保持三个 Cube 旋转都为 0,可以看到两个子物体是绕着自己的 up 轴旋转的。

将两个子物体的旋转的 x 轴改为 45,可以看到两个子物体是绕着自己的 up 轴旋转的。

将父物体的旋转 x 轴也改成 45,可以看到两个子物体还是绕着自己的 up 轴旋转的。

上面两种写法永远相等,原因参考一些事实中第一点。
让物体绕世界坐标轴旋转
using UnityEngine;
public class QuaternionTest : MonoBehaviour
{
public Transform childCube1;
void Update()
{
Quaternion rotU = Quaternion.AngleAxis(200 * Time.deltaTime, Vector3.up);
childCube1.transform.rotation = rotU * childCube1.transform.rotation;
}
}
还是保持三个 Cube 旋转都为 0,可以看到子物体是绕着世界 up 轴旋转的。

将子物体的旋转的 x 轴改为 45,并把显示的坐标轴从 Local 变成 Global,可以看到子物体依然绕着世界 up 轴旋转。

将父物体的旋转 x 轴也改成 45,可以看到子物体依然绕着世界 up 轴旋转。

让物体绕父物体某一个轴旋转
代码如下:
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public Transform childCube1;
void Update()
{
Quaternion rotU = Quaternion.AngleAxis(200 * Time.deltaTime, Vector3.up);
childCube1.transform.localRotation = rotU * childCube1.transform.localRotation;
}
}
将父物体的 x 轴旋转设置为 90,将子物体的 x 轴旋转设置为 -90,可以看到子物体是按照父物体的 up 轴进行旋转的。

总结
所有的旋转都是顺时针的。
参考
https://www.cnblogs.com/ChenZiRong1999/p/13186315.html?utm_source=tuicool
网友评论