RealityKit——让物体始终在屏幕前

RealityKit – Keep object always in front of screen

我正在使用以下代码将对象保持在屏幕前并随相机移动它。在 didUpdate frame: ARFrame 委托上,我调用 getCameraPosition()。 一切都很完美, 现在我需要一个有效的解决方案来缩短处理时间。在当前的解决方案中,我觉得 phone 有时会挂起。如果 existingPlaneInfinite 和 estimatedPlane 不可用怎么办? 这是我所做的视频 link

  extension ARView {
        
        func getCameraPosition(from: CGPoint? = nil) -> Position {
            
            let from = from ?? self.center
            var result: ARRaycastResult?
            if let raycast = self.raycast(from: from,
                                          allowing: .existingPlaneInfinite,
                                          alignment: .horizontal).last {
                result = raycast
            } else if let raycast = self.raycast(from: from,
                                                 allowing: .estimatedPlane,
                                                 alignment: .horizontal).last {
                result = raycast
            }
            return result?.worldTransform.getPosition() ?? .zero
            
        }
    }

func session(_ session: ARSession, didUpdate frame: ARFrame) {
     
        if self.viewModel.isFirstHorizontalPlanDetected {
            DispatchQueue.main.async {
                self.object.position =  self.arView.currentPositionOfCamera()
            }
        }           
    }

这种情况下最好的解决办法是使用trackedRaycast方法:

let query: ARRaycastQuery = .init(origin: SIMD3<Float>(),
                               direction: SIMD3<Float>(),
                                allowing: .estimatedPlane,
                               alignment: .horizontal)

let repeated = arView.session.trackedRaycast(query) { results in
 
    guard let result: ARRaycastResult = results.first
    else { return }
        
    let anchor = AnchorEntity(world: result.worldTransform)
    anchor.addChild(model)
    arView.scene.anchors.append(anchor)
}
    
repeated?.stopTracking()

此外,您必须实现 ray(through:) 实例方法:

@MainActor func ray(through screenPoint: CGPoint) -> (origin: SIMD3<Float>, 
                                                   direction: SIMD3<Float>)?