我在SCNode碰撞检测中遇到了一些麻烦。我需要检测具有SCNNode的场景中的哪个对象被触摸,我已经实现了这段代码,但是当我触摸对象时看起来崩溃,但是当我触摸sceneView的其余部分时工作正常。如何检测哪个SCNNode已被触摸ARKit
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")
}
}
}
1。事实上在问题中没有提到,但是如果你真的想假设在针对该节点执行命中测试之前它可能为零,那么在进行命中测试之前实际执行该检查将是有意义的。 – Xartec
P2。除了无效的contains方法,没有理由假设bottleNode具有childnodes,但是如果是这种情况,是否有任何增加值使用自定义扩展来遍历结果节点的父母,而不是简单地检查bottlenode childnodes是否包含结果节点? (即瓶子节点上的enumerateHierarchy将避免检查结果节点的所有父母)。我确信在复制并粘贴代码后,结果会是由于扩展名为self == node部分,所以我不认为这应该是被接受的答案。 – Xartec
@Xartec好点。不知道所讨论的节点层次结构,我选择了一种通常在算法上高效的解决方案。向上移动父层次由节点树的高度限制,但是搜索目标节点的子子树受该子树的整个宽度限制。对于任意大树中的任何点,最坏情况下的子树大小可能远大于回到根的高度。但是值得考虑一下你期望在你的应用中使用的节点层次结构 - 如果它非常平坦,那么对测试节点进行简单的指针相等测试就足够了。 – rickster