【问题标题】:How to do a hitTest on subnodes of node in sceneView?如何对sceneView中节点的子节点进行hitTest?
【发布时间】:2018-10-10 12:55:42
【问题描述】:

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

我的问题是,视图一直在我在“我的图像节点”中添加为子节点的节点上方添加一个不可见的平面节点,当我将 TapGestureRecognizer 添加到场景视图时,我无法检测到节点,因为它检测到平面。有时它可以工作,但是当它添加飞机时它就不起作用了。

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

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

▿ 3 个元素 - 0:|没有孩子> - 1:SCNNode:0x1c41f4100 |光= - 2 : SCNNode: 0x1c43e1000 'DetectableChildrenParent' 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 'DetectableChildrenParent' pos(-0.149971 0.050361 -0.365586) rot(0.996908 0.061535 -0.048872 1.379775) scale(1.000000 1.000000 1.0000) 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 ?? "")
            }
    }

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

【问题讨论】:

    标签: ios swift augmented-reality arkit hittest


    【解决方案1】:

    假设我正确解释了您的问题,您正在寻找的是 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)
        }
    
    
    }
    

    希望对你有帮助...

    【讨论】:

    • 不,是一样的,因为不可见节点3 SCNNode: 0x1c01f9f00 |几何= |没有孩子> 超过 2 : SCNNode: 0x1c01fd100 'DetectableChildrenParent' pos(-0.149971 0.050361 -0.365586) rot(0.996908 0.061535 -0.048872 1.379775) scale(1.0000000 1.00000000000000001。 2 个孩子> 它在 hitTestResultNode 中检测为该节点,但谢谢
    • 节点名称是否为“DetectableChildrenParent”?
    • 没有我试图检测名称的具有子节点的节点是“DetectableChildrenParent”,它有 2 个子节点。我正在尝试检测这些节点,并且仅检测这些节点。
    • 感谢您的尝试,但它完全相同,因为在行中 let hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first?.node else { return } 它检测到节点 3 SCNNode: 0x1c01f9f00 |几何= |没有孩子>所以名字无关紧要
    • 试着让 hitTestResultNode = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).last
    猜你喜欢
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 2019-07-14
    • 2015-05-15
    • 2018-11-28
    • 2015-05-17
    • 2021-03-14
    相关资源
    最近更新 更多