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)
这里存在多个问题,现有的答案只涉及其中的一些问题.
从你发布的代码中不清楚bottleNode这个方法运行时是否可以为nil.当值为nil时通过可选(?in bottle?.contains)调用方法将无声地失败 - 导致整个表达式结果包含在一个Optional中,其值为nil - 但是你有一个parens和一个强力解包整个表达式,所以nil-unwrap会崩溃.
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检查非常简单,或者如果您正在寻找包含/重叠,八叉树可能会有所帮助.