如何获取手势平移操作后Entity的最新变换矩阵用于创建ARAnchor
问题根因
直接读取Entity.transform.matrix拿到的是实体相对于父节点的本地变换矩阵。你在添加子实体时设置了preservingWorldTransform: true,且平移手势默认修改的是实体的世界空间位姿,不会自动同步更新本地transform属性,因此读到的矩阵始终是初始值。同时你使用的平面类型AnchorEntity的位姿由ARKit平面检测结果驱动,本身也不适合手动修改变换属性。
获取最新变换矩阵的方案
方案1:直接读取世界空间变换矩阵(推荐)
不需要修改现有逻辑,调用实体的transformMatrix(relativeTo:)方法,传入nil即可获取实时同步的世界坐标系变换矩阵,不受父节点位姿、本地transform初始值的影响:
guard let modelEntity = uiView.scene.findEntity(named: "Model_Name") else { return } // 获取最新世界变换矩阵 let latestWorldTransform = modelEntity.transformMatrix(relativeTo: nil)
拿到矩阵后可以直接提取位置信息创建ARAnchor:
// 从4x4变换矩阵提取平移分量 let position = SIMD3<Float>( latestWorldTransform.columns.3.x, latestWorldTransform.columns.3.y, latestWorldTransform.columns.3.z ) // 初始化ARAnchor,需要保留模型当前旋转信息可直接传入整个矩阵 let newARAnchor = ARAnchor(transform: latestWorldTransform) // 添加到ARSession生效 uiView.session.add(anchor: newARAnchor)
方案2:手势结束后同步变换到本地属性
如果后续需要频繁读取本地transform.matrix属性,可以在平移手势的结束状态回调中,把当前世界变换同步到实体的本地transform:
@objc func handleModelTranslation(_ recognizer: EntityTranslationGestureRecognizer) { guard let targetEntity = recognizer.entity else { return } switch recognizer.state { case .ended: // 将当前世界位姿写入本地transform targetEntity.transform = Transform(matrix: targetEntity.transformMatrix(relativeTo: nil)) // 后续读取targetEntity.transform.matrix即可拿到最新值 default: break } }
注意事项
不要在手势拖动的每帧回调中同步本地transform,会导致拖动卡顿、位置跳变。
不要手动修改平面检测生成的AnchorEntity的transform属性,它的位姿由ARKit内部更新,手动修改的值会被系统自动覆盖。
内容的提问来源于stack exchange,提问作者George Barmpas
相关产品推荐
相关产品推荐

