如何检测哪个SCNNode已被触摸ARKit

Pie*_*neo 5 scenekit swift scnnode arkit

我在SCNode命中检测方面遇到了一些麻烦.我需要检测哪个对象是在具有SCNNode的情景感动了,我已经实现了这一段代码,但它似乎当我接触的对象,但做工不错,当我接触sceneView其余崩溃.

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 (bottleNode?.contains(result.node))! { //bottleNode is declared as  SCNNode? and it's crashing here
                print("match")
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)

ric*_*ter 5

这里存在多个问题,现有的答案只涉及其中的一些问题.

  1. 从你发布的代码中不清楚bottleNode这个方法运行时是否可以为nil.当值为nil时通过可选(?in bottle?.contains)调用方法将无声地失败 - 导致整个表达式结果包含在一个Optional中,其值为nil - 但是你有一个parens和一个强力解包整个表达式,所以nil-unwrap会崩溃.

  2. contains(_:)不是一个方法SCNNode.目前还不清楚bottleNode你甚至可以在没有编译器错误的情况下编写这个方法调用的类型...但是如果bottleNode实际上是一个SCNNode并且你已经完成了一些类型擦除/ Any-casting goop以允许调用编译,那么调用将是由于不存在的方法,在运行时失败.

如果您使用该bottleNode.contains行的目标是确定命中测试结果bottleNode本身还是其子节点,我建议您定义并使用这样的扩展方法:

extension SCNNode {
    func hasAncestor(_ node: SCNNode) -> Bool {
        if self === node {
            return true // this is the node you're looking for
        }
        if self.parent == nil {
            return false // target node can't be a parent/ancestor if we have no parent
        } 
        if self.parent === node {
            return true // target node is this node's direct parent
        }
        // otherwise recurse to check parent's parent and so on
        return self.parent.hasAncestor(node)
    }
}

// in your touchesBegan method...
if let bottleNode = bottleNode, result.node.hasAncestor(bottleNode) { 
    print("match")
}
Run Code Online (Sandbox Code Playgroud)

相反,如果你的目标是确定是否result.node位于边界框内或与边界框重叠bottleNode(无论节点层次结构如何),回答这个问题会更复杂一些.一个简单的position内部boundingSphere检查非常简单,或者如果您正在寻找包含/重叠,八叉树可能会有所帮助.