首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ARKit中检测SCNNode上的触摸

在ARKit中检测SCNNode上的触摸
EN

Stack Overflow用户
提问于 2018-02-19 00:50:47
回答 2查看 3.4K关注 0票数 1

在ARKit 1.5测试版中,我已经在可识别图像的位置放置了一个SCNNode (平面)。当飞机被点击时,我想在控制台上打印一条消息。到目前为止,我有以下代码:

代码语言:javascript
复制
// MARK: - ARSCNViewDelegate (Image detection results)
    /// - Tag: ARImageAnchor-Visualizing
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        guard let imageAnchor = anchor as? ARImageAnchor else { return }
        let referenceImage = imageAnchor.referenceImage
        updateQueue.async {

            // Create a plane to visualize the initial position of the detected image.
            let plane = SCNPlane(width: referenceImage.physicalSize.width,
                                 height: referenceImage.physicalSize.height)
            let planeNode = SCNNode(geometry: plane)
            planeNode.opacity = 0.25

            /*
             `SCNPlane` is vertically oriented in its local coordinate space, but
             `ARImageAnchor` assumes the image is horizontal in its local space, so
             rotate the plane to match.
             */
            planeNode.eulerAngles.x = -.pi / 2

            /*
             Image anchors are not tracked after initial detection, so create an
             animation that limits the duration for which the plane visualization appears.
             */
            //planeNode.runAction(self.imageHighlightAction)

            // Add the plane visualization to the scene.
            node.addChildNode(planeNode)
        }

        DispatchQueue.main.async {
            let imageName = referenceImage.name ?? ""
            self.statusViewController.cancelAllScheduledMessages()
            self.statusViewController.showMessage("Detected image “\(imageName)”")
        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first as! UITouch
        if(touch.view == self.sceneView){
            print("touch working")
            let viewTouchLocation:CGPoint = touch.location(in: sceneView)
            guard let result = sceneView.hitTest(viewTouchLocation, options: nil).first else {
                return
            }
            if let planeNode = planeNode, planeNode == result.node {
                print("match")
            }

        }
    }

但是我在这一行得到了一个“未解析的标识符”错误:if let planeNode = planeNode, planeNode == result.node {,我理解它是因为planeNode是在上面的渲染器函数中定义的,并且没有在正确的作用域中。我的问题是如何解决这个问题,因为我不相信我可以在渲染器中返回值,也不能将touchesBegan函数放在渲染器函数中以使其处于正确的作用域。谁能给我一些关于如何解决这个问题的建议?谢谢!

EN

回答 2

Stack Overflow用户

发布于 2018-08-18 17:36:57

要解决此问题,请在ViewController中声明一个全局变量

代码语言:javascript
复制
class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    var planeNode : SCNNode? = nil

    .....

}

然后使用刚刚声明的planeNode变量,并将其赋给planeNode方法中的实际渲染器

代码语言:javascript
复制
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {

     .........

     let planeNode = SCNNode(geometry: plane)
     self.planeNode = planeNode
}

这样,您就可以从类中的任何位置访问planeNode

代码语言:javascript
复制
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let touch = touches.first as! UITouch
    if(touch.view == self.sceneView){
        print("touch working")
        let viewTouchLocation:CGPoint = touch.location(in: sceneView)
        guard let result = sceneView.hitTest(viewTouchLocation, options: nil).first else {
            return
        }
        if let planeNode = planeNode, planeNode == result.node {
            print("match")
        }

    }
}
票数 3
EN

Stack Overflow用户

发布于 2018-09-25 19:28:15

代码语言:javascript
复制
// Add a gesture recognizer
 let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
    self.sceneView.addGestureRecognizer(tapGestureRecognizer)
    tapGestureRecognizer.cancelsTouchesInView = false 

@objc func handleTap(发送者:UITapGestureRecognizer){

代码语言:javascript
复制
    guard let sceneView = sender.view as? ARSCNView else {return}
    let touchLcoation = sender.location(in: sceneView)
    let hitTestResult = sceneView.hitTest(touchLcoation, types: .existingPlaneUsingExtent)

    if !hitTestResult.isEmpty {
        // add something to scene 
        // e.g self.sceneView.scene.rootNode.addChildNode(yourNode!)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48854151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档