Unity中如何利用子物体的localPosition和localRotation对齐父物体(二维码场景)
基于二维码识别对齐AR父物体
需求背景
在编辑器中,将汽车模型设为父物体(parent),在其侧后视镜上放置二维码并保存该二维码相对于父物体的localPosition和localRotation(即代码中的localQrPosition、localQrRotation),同时在引擎盖中心放置AR应用中要显示的3D模型。当真实汽车侧后视镜的二维码被AR应用识别后,需要通过预存的参数让虚拟父物体(汽车模型)与真实汽车对齐。现有代码看似能运行,但计算逻辑存在错误,需要修正。
原错误代码
public class StickyParent : MonoBehaviour { [SerializeField] Transform parent; [SerializeField] Transform qrCode; [SerializeField] Vector3 localQrPosition; [SerializeField] Vector3 localQrRotation; public void Align() { if (parent == null) return; var fixedPos = new Vector3(-localQrPosition.x, -localQrPosition.y, localQrPosition.z); // 不得不反转x和y才能得到正确结果,但不知道原因... var trackedPosition = qrCode.TransformPointUnscaled(fixedPos); // 忽略缩放的TransformPoint扩展方法 var trackedRotation = qrCode.rotation * Quaternion.Euler(localQrRotation); parent.position = trackedPosition; parent.rotation = trackedRotation; } }
错误分析与正确逻辑
原代码的核心问题是没有正确处理坐标变换的逆运算。我们的目标是:已知真实二维码的世界位姿(qrCode的position和rotation),以及编辑器中二维码相对于虚拟父物体的位姿,反推虚拟父物体的世界位姿,让虚拟空间内二维码与父物体的相对关系,和真实空间中二维码与真实汽车的相对关系完全匹配。
正确的数学推导:
- 旋转计算:父物体的世界旋转 = 二维码的世界旋转 × (二维码相对于父物体的局部旋转)的逆旋转
- 位置计算:父物体的世界位置 = 二维码的世界位置 - (二维码的世界旋转 × 二维码相对于父物体的局部位置)
修正后的代码
public class StickyParent : MonoBehaviour { [SerializeField] Transform parent; [SerializeField] Transform qrCode; [SerializeField] Vector3 localQrPosition; [SerializeField] Vector3 localQrRotation; public void Align() { if (parent == null || qrCode == null) return; // 将预存的局部旋转转为四元数 Quaternion localQrRot = Quaternion.Euler(localQrRotation); // 计算父物体的旋转:二维码世界旋转 × 局部旋转的逆 parent.rotation = qrCode.rotation * Quaternion.Inverse(localQrRot); // 计算父物体的位置:二维码世界位置减去旋转后的局部位置偏移 Vector3 offset = qrCode.rotation * localQrPosition; parent.position = qrCode.position - offset; } }
补充说明
原代码中手动反转x/y轴能凑效,大概率是因为AR识别的坐标系与Unity编辑器的坐标系轴方向存在反转,但这是偶然适配的结果,不具备通用性。正确的逆变换计算无需依赖手动调整轴方向,能在所有坐标系下稳定工作。
内容的提问来源于stack exchange,提问作者KarlSupertramp
相关产品推荐
相关产品推荐

