首页 > 解决方案 > RealityKit – trackedRaycast 的 updateHandler 未调用

问题描述

我从哪调用trackedRaycast()从哪startTracing()调用viewDidLoad()。我的目标是将 AR 内容放置在来自相机的光线投射到水平表面的任何地方,并且当光线投射与不同的位置相交时它会更新。当用户点击屏幕时,更新停止。trackedRaycast 函数的 updateHandler 闭包永远不会执行。

import RealityKit
import ARKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    
    var gameAnchor: Experience.PreviewBoard!
    var raycast: ARTrackedRaycast?
    var gameIsPlaced = false
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupARConfiguration()
        loadGameBoard()
        startTracing()
        
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:)))
        arView.addGestureRecognizer(tapGestureRecognizer)
    }
    
    func setupARConfiguration() {
        arView.automaticallyConfigureSession = false
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = [.horizontal]
        config.isCollaborationEnabled = true
        config.environmentTexturing = .automatic
        arView.session.run(config)
    }
    
    func loadGameBoard() {
        gameAnchor = try! Experience.loadPreviewBoard()
        arView.scene.addAnchor(gameAnchor)
    }
    
    func startTracing() {
        raycast = arView.trackedRaycast(from: view.center, allowing: .estimatedPlane, alignment: .horizontal) { results in
            print("This is never executed")
            // Refine the game position with raycast update
            if let result = results.first {
                self.gameAnchor.setTransformMatrix(result.worldTransform, relativeTo: nil)
            }
        }
    }
    
    func stopTracing() {
        print("raycast has stopped")
        raycast?.stopTracking()
    }
    
    @objc func handleTap(recognizer: UITapGestureRecognizer) {
        if !gameIsPlaced {
            gameIsPlaced = true
            stopTracing()
        }
    }
}

可能是什么问题?

标签: swiftaugmented-realityarkitraycastingrealitykit

解决方案


初始化视图时似乎存在某种滞后,导致跟踪的光线投射未从通常的生命周期方法初始化。当我尝试通过点击屏幕对其进行初始化时,它按预期工作。您可以使用以下代码进行检查:

    var r : ARTrackedRaycast? {
        didSet {
            print("Raycast initialized")
        }
    }
    
    r = self.arView.trackedRaycast(from: self.view.center, allowing: .existingPlaneInfinite, alignment: .any) { result in
        print("Callback received")
    }

如果您从viewDidLoad()viewDidAppear()什至初始化您的光线投射,则永远不会调用设置器。

我的解决方案是将光线投射的初始化延迟几秒钟,如下所示:

    DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
        r = self.arView.trackedRaycast(from: self.view.center, allowing: .existingPlaneInfinite, alignment: .any) { result in
            print("Callback received")
    }

显然,这远非理想,但现在我不确定如何以不同的方式解决这个问题。


推荐阅读