scenekitios11arkitxcode9beta6

How to create a border for SCNNode to indicate its selection in iOS 11 ARKit-Scenekit?


How to draw a border to highlight a SCNNode and indicate to user that the node is selected? In my project user can place multiple virtual objects and user can select any object anytime. Upon selection i should show the user highlighted 3D object. Is there a way to directly achieve this or draw a border over SCNNode?


Solution

  • You need to add a tap gesture recognizer to the sceneView.

    // add a tap gesture recognizer
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
    scnView.addGestureRecognizer(tapGesture)
    

    Then, handle the tap and highlight the node:

    @objc
    func handleTap(_ gestureRecognize: UIGestureRecognizer) {
        // retrieve the SCNView
        let scnView = self.view as! SCNView
    
        // check what nodes are tapped
        let p = gestureRecognize.location(in: scnView)
        let hitResults = scnView.hitTest(p, options: [:])
        // check that we clicked on at least one object
        if hitResults.count > 0 {
            // retrieved the first clicked object
            let result = hitResults[0]
    
            // get its material
            let material = result.node.geometry!.firstMaterial!
    
            // highlight it
            SCNTransaction.begin()
            SCNTransaction.animationDuration = 0.5
    
            // on completion - unhighlight
            SCNTransaction.completionBlock = {
                SCNTransaction.begin()
                SCNTransaction.animationDuration = 0.5
    
                material.emission.contents = UIColor.black
    
                SCNTransaction.commit()
            }
    
            material.emission.contents = UIColor.red
    
            SCNTransaction.commit()
        }
    }
    

    The snippet above highlights the whole node. You'd have to adjust it to highlight the borders only, if that's what you're looking for.

    Disclaimer:
    This code was taken directly from Xcode's template code created when opening a new game (SceneKit) project.