如何在移动手机时保持AR平面固定在识别图像上方?
解决ARKit图像识别后平面位置偏移问题
你的问题出在错误地使用了世界空间锚点,没有让平面和ARKit跟踪的图像锚点绑定。当手机移动时,ARKit会实时更新imageAnchor的世界坐标,但你初始化的AnchorEntity(world: imageAnchor.transform)是固定在初始位置的,不会跟随图像锚点的更新,导致平面出现偏移。
正确解决方案:绑定平面到图像锚点实体
- 创建关联图像锚点的锚点实体
直接基于识别到的imageAnchor创建锚点,ARKit会自动管理它的位置更新:let imageAnchorEntity = AnchorEntity(anchor: imageAnchor) arView.scene.addAnchor(imageAnchorEntity) - 将平面设为图像锚点的子节点
生成平面实体并设置好VideoMaterial后,添加到图像锚点实体下,同时调整相对位置让平面悬浮在图像上方:// 根据识别图像的物理尺寸生成平面 let planeSize = imageAnchor.referenceImage.physicalSize let planeMesh = MeshResource.generatePlane(width: planeSize.width, height: planeSize.height) let planeEntity = ModelEntity(mesh: planeMesh, materials: [yourVideoMaterial]) // 调整平面Z轴位置,让它在图像上方(单位:米) planeEntity.position = SIMD3(0, 0, 0.01) // 将平面添加到图像锚点实体中 imageAnchorEntity.addChild(planeEntity) - 无需手动更新
ARKit会在每次imageAnchor更新时自动同步锚点实体的世界变换,平面作为子节点会始终保持和图像的相对位置,不会随手机移动而偏移。
备选方案:手动更新世界锚点(不推荐)
如果一定要使用独立的世界锚点,可在didUpdate方法中同步图像锚点的变换:
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { for anchor in anchors { guard let updatedImageAnchor = anchor as? ARImageAnchor else { continue } // 找到你之前创建的世界锚点(建议给锚点设置name来区分) guard let worldAnchor = arView.scene.anchors.first(where: { $0.name == "PlaneAnchor" }) as? AnchorEntity else { continue } // 同步图像锚点的最新世界变换 worldAnchor.transform = updatedImageAnchor.transform } }
这种方式需要额外管理锚点的查找和更新,不如直接绑定图像锚点的方案简洁可靠。
内容的提问来源于stack exchange,提问作者janineanne
相关产品推荐
相关产品推荐

