准备
- Transform.TransformPoint方法
本地空间的点转换为世界空间的点 - Transform.InverseTransformPoint
世界空间的点转换到相对于变换本地空间的点 - 四元数 q1 * q2 得到一个四元数,表示先旋转q2,再旋转q1。
- Quaternion.Inverse得到一个四元数,表示相反方向的旋转。
例如,如果有一个旋转四元数表示绕Y轴旋转30度,那么它的逆就是绕Y轴旋转-30度
思路
子对象和父对象不存在真实的父子关系,使用脚本模拟。

位置
获取相对点:获取子对象在世界空间的点,使用InverseTransformPoint方法将该点转换为相对于父对象本地空间的点;
更新位置:父对象位置改变,使用TransformPoint方法,将相对于父对象本地空间的点转换到世界空间,更新子对象位置。
旋转
获取相对旋转:使用Quaternion.Inverse得到父对象的逆四元数,父对象的逆四元数与子对象的四元数相乘,得到相对旋转;
更新旋转:父对象角度改变,将父对象四元数与相对四元数相乘得到相对于父对象的旋转,更新子对象旋转。
示例
csharp
using UnityEngine;
public class Lesson1 : MonoBehaviour
{
public Transform parent;
public Transform[] children;
Vector3[] relativePosition;
Quaternion[] relativeAngle;
void Start()
{
relativePosition = new Vector3[children.Length];
relativeAngle = new Quaternion[children.Length];
for (int i = 0; i < children.Length; i++)
{
relativePosition[i] = parent.InverseTransformPoint(children[i].position);
relativeAngle[i] = Quaternion.Inverse(parent.rotation) * children[i].rotation;
}
}
void Update()
{
for (int i = 0; i < children.Length; i++)
{
var position = parent.TransformPoint(relativePosition[i]);
var angle = parent.rotation * relativeAngle[i];
children[i].SetPositionAndRotation(position, angle);
}
}
}