11

I'm new to this and currently building an AR-related application, on the old version I stated this

let results = self.hitTest(screenPosition, types: [.featurePoint])

and now I have a problem where the hitTest is deprecated in iOS 14.0

hitTest(_:types:)' was deprecated in iOS 14.0: Use [ARSCNView raycastQueryFromPoint:allowingTarget:alignment]

please advise me on how to fix it, thank you :)

Zaky Putra
  • 111
  • 1
  • 4
  • you should use `raycastQuery(from:allowing:alignment:)` to do this. could you please check this to understand what is it and how can you use it -> https://stackoverflow.com/q/60073349/7512091 – emrcftci Oct 08 '20 at 08:23

3 Answers3

6

Yes, use raycastQuery(from:allowing:alignment:)

as suggested by Xcode in this way:

...
let location = gesture.location(in: sceneView)
guard let query = sceneView.raycastQuery(from: location, allowing: .existingPlaneInfinite, alignment: .any) else {
   return
}
        
let results = sceneView.session.raycast(query)
guard let hitTestResult = results.first else {
   print("No surface found")
   return
}
...
Peter Karena
  • 71
  • 1
  • 1
2

You can assign a node with a name and then use hitTest(point:, options:[SCNHitTestOption : Any]?) in touchesBegan. Below is the code I used:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let touchLocation = touch.location(in: sceneView)
        let results = sceneView.hitTest(touchLocation, options: [SCNHitTestOption.searchMode : 1])
        
        for result in results.filter({$0.node.name != nil}) {
            if result.node.name == "planeNode" {
                print("touched the planeNode")
            }
        }
    }
}
0

Don't forget to set configuration.planeDetection in viewWillAppear before using the code below, I assume that you want to use in touchesBegan method

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    let configuration = ARWorldTrackingConfiguration()
    
    configuration.planeDetection = .horizontal

    sceneView.session.run(configuration)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
    guard let touchLocation = touches.first?.location(in: sceneView) else {return}
    
    guard let query = sceneView.raycastQuery(from: touchLocation, allowing: .existingPlaneGeometry, alignment: .any) else {return}
    
    let results = sceneView.session.raycast(query)

    //this is the answer to your question, then you may want to get first result, then

    if let hitResult = results.first{
                
         //do what you want
                
    }
}
Akif
  • 73
  • 5