RealityKit - updateHandler для trackedRaycast не вызывается

Я звоню trackedRaycast() из startTracing(), который вызывается из viewDidLoad(). Моя цель состоит в том, чтобы контент AR размещался там, где луч лучей камеры попадает на горизонтальную поверхность, и чтобы он обновлялся, когда луч луча пересекает другое место. Когда пользователь касается экрана, обновления останавливаются. Закрытие updateHandler функции trackedRaycast никогда не выполняется.

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()
        }
    }
}

В чем может быть проблема?


person Isaak    schedule 08.07.2020    source источник


Ответы (1)


Похоже, что при инициализации представления происходит какая-то задержка, что приводит к тому, что отслеживаемый raycast не инициализируется обычными методами жизненного цикла. Когда я попытался инициализировать его, нажав на экран, все заработало, как задумано. Вы можете проверить это с помощью следующего кода:

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

Если вы инициализируете свой raycast с viewDidLoad() или даже viewDidAppear(), сеттер никогда не вызывается.

Решением для меня было отложить инициализацию raycast на несколько секунд, вот так:

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

Это, очевидно, далеко от идеала, но сейчас я не знаю, как решить эту проблему иначе.

person Daniel_D    schedule 18.07.2020