Search code examples
swiftaugmented-realityscenekitarkitrealitykit

Lazy var for playing audio when reference image is detected


I would like to play individual audio files from reference images.

Would I use a lazy var to load the audio file and then use

func getNode(withImageName name: String) 

to trigger which audio to play?


Solution

  • Yes, you can.

    If you wanna know how to use SceneKit positional audio read this post.

    In case you use RealityKit positional audio in your app – read this post.


    Let's see how your code may look like for lazy var:

     lazy var geoAndAudioNode: SCNNode = {
        
        guard let scene: SCNScene = SCNScene(named: "pixar.usdz"),
              let node: SCNNode = scene.rootNode.childNode(withName: "model", 
                                                        recursively: true)
        else { return SCNNode() }
        
        let myPath = Bundle.main.path(forResource: "audio", ofType: "mp3")
        let myURL = URL(fileURLWithPath: myPath!)
        let mySource = SCNAudioSource(url: myURL)!
        
        let audioNode = SCNNode()
        let player = SCNAudioPlayer(source: mySource)
        node.addChildNode(audioNode)
        audioNode.addAudioPlayer(player)
        
        return node
    }()
    

    And here's how your code may look like inside renderer method:

    extension ViewController: ARSCNViewDelegate {
        
        func renderer(_ renderer: SCNSceneRenderer,
                     didAdd node: SCNNode,
                      for anchor: ARAnchor) {
            
            guard let imageAnchor = anchor as? ARImageAnchor,
                  let imageName = imageAnchor.referenceImage.name
            else { return }
                        
            let geometryNode = retrieveNode(name: imageName)
            node.addChildNode(geometryNode)
        }
        
        func retrieveNode(name: String) -> SCNNode {
            
            var node = SCNNode()
            
            switch name {
                case "geoAndAudioImage": node = geoAndAudioNode
                default: break
            }
            return node
        }
    }