如何在场景视图中对节点的子节点进行命中测试?



我有一个ARSceneView,我使用检测图像来查找平面,以便我可以根据检测到的图像添加节点。

我的问题是,视图一直在我在"图像节点"中作为子节点添加的节点上方添加一个不可见的平面节点,当我向 sceneView 添加 TapGestureRecognizer 时,我无法检测到该节点,因为它检测到平面。有时它有效,但是当它添加平面时,它不起作用。

当飞机在现场时,我的节点是这些

我希望我的节点是这样的。

▿ 3 元素 - 0 : |没有孩子> - 1 : SCNNode: 0x1c41f4100 |光= - 2 : SCNNode: 0x1c43e1000 "可检测儿童父母" pos(-0.009494 -0.081575 -0.360098( rot(0.997592 -0.060896 0.033189 1.335512( |2名儿童>

和我的 2 个孩子只是可检测的节点。.

但总是这样

▿ 4 元素 - 0 : SCNNode: 0x1c01fcc00 pos(-0.093724 0.119850 -0.060124( rot(-0.981372 0.172364 -0.084866 0.457864( scale(1.000000 1.000000 1.000000( |相机= |没有孩子> - 1 : SCNNode: 0x1c01fc200 |光= |没有孩子> - 2 : SCNNode: 0x1c01fd100 "可检测的孩子父母" pos(-0.149971 0.050361 -0.365586( rot(0.996908 0.061535 -0.048872 1.379775( 规模(1.000000 1.000000 1.000000( |2名儿童> - 3 : SCNNode: 0x1c01f9f00 |几何= |没有孩子>

它总是检测到最后一个节点。

我要检测的代码是这个

@objc func addNodeToScene(withGestureRecognizer recognizer: UIGestureRecognizer) {
let tapLocation = recognizer.location(in: self.sceneView)
let hitTestResults = sceneView.hitTest(tapLocation)
if let node = hitTestResults.first?.node {
print(node.name ?? "")
}
}

如何运行命中测试以仅检查可检测子项的子项?

假设我已经正确解释了您的问题,那么您正在寻找的是SCNHitTestResult NodechildNodes属性,它指的是:

场景图层次结构中节点的子节点数组。

因此,我相信您可以尝试这样的事情:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Location
guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView),
//2. Get The Tapped Node From An SCNHitTest
let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first?.node else { return }
//3. Loop Through The ChildNodes
for node in hitTestResultNode.childNodes{
//4. If The Node Has A Name Then Print It Out
if let validName = node.name{
print("Node(validName) Is A Child Node Of (hitTestResultNode)")
}
}
}

或者,与其寻找SCNHitTest的第一个结果,不如尝试通过查找最后一个结果来尝试,例如:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Location
guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView),
//2. Get The Tapped Node From An SCNHitTest
let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).last?.node else { return }
//3. Loop Through The ChildNodes
for node in hitTestResultNode.childNodes{
//4. If The Node Has A Name Then Print It Out
if let validName = node.name{
print("Node(validName) Is A Child Node Of (hitTestResultNode)")
}
}
}

如果要查找特定SCNNode的子项,请使用以下内容:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Location
guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView),
//2. Get The Tapped Node From An SCNHitTest
let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first?.node else { return }
//3. If The Name Of The Nodes Is Equal To DetectableChildrenParent Then Get The Children
if hitTestResultNode.name == "DetectableChildrenParent"{
let childNodes = hitTestResultNode.childNodes
print(childNodes)
}
}

或者,您也可以像这样简单地遍历SCNHitTestResults

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Location
guard let currentTouchLocation = touches.first?.location(in: self.augmentedRealityView) else { return }
//2. Get The Results Of The SCNHitTest
let hitTestResults = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil)

//3. Loop Through Them And Handle The Result
for result in hitTestResults{
print(result.node)
print(result.node.childNodes)
}

}

希望对你有帮助...

最新更新