将SCNNode放置在平面上并检测到该节点已被轻击

时间:2018-09-20 12:28:16

标签: ios swift arkit scnnode sceneview

我正在开发一个应用程序,该应用程序首先检测到有一个垂直平面,然后,如果用户触摸该平面,我会向根节点添加一个SCNNode。之后,我想检测用户是否触摸节点以执行更多操作,但是我无法检测到该轻拍,它仅检测平面轻拍。现在,我回到了这种方法:

    @objc func tapped(sender: UITapGestureRecognizer) {
        let sceneView = sender.view as! ARSCNView
        let tapLocation = sender.location(in: sceneView)
        let hitTest = sceneView.hitTest(tapLocation, types: .existingPlaneUsingExtent)
        if !hitTest.isEmpty {
            addItem(hitTestResult: hitTest.first!)
            hideTip()
    }
}

哪个是在飞机上点击时添加节点的人,但是现在我想检测何时点击节点,我使用了以下代码:

    let sceneView = sender.view as! ARSCNView
    let tapLocation = sender.location(in: sceneView)
    let hitTouchTest = sceneView.hitTest(tapLocation)
    if !hitTouchTest.isEmpty {
        let results = hitTouchTest.first!
        let node = results.node
    }

它输入if,但是节点的名称始终为nil,当我创建将节点添加到飞机上的节点时,我给它命名...如何检测节点是否被点击?

1 个答案:

答案 0 :(得分:2)

此解决方案的问题在于,您要获取已触摸节点阵列的第一个值。 我建议阅读下一个主题: https://developer.apple.com/documentation/scenekit/scnhittestoption

您可以实施的解决方案:

func registerGestureRecognizer() {
    let tap = UITapGestureRecognizer(target: self, action: #selector(search))
    self.sceneView.addGestureRecognizer(tap)
}

@objc func search(sender: UITapGestureRecognizer) {
    let sceneView = sender.view as! ARSCNView
    let location = sender.location(in: sceneView)
    let results = sceneView.hitTest(location, options: [SCNHitTestOption.searchMode : 1])

    guard sender.state == .began else { return }
        for result in results.filter( { $0.node.name != nil }) {
            if result.node.name == "Your node name" {
                // do manipulations
            }
        }
}

P.S。这种方法可帮助您通过其名称获取特定节点。 希望对您有帮助!