Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SceneKit Audio - How to add a SCNPlayer to a SCNNode and just play back a sound

I'm currently using this code (inside a SCNNode subclass) to play back a sound in SceneKit.

    let audioSource = SCNAudioSource(named: "coin.wav")
    let audioPlayer = SCNAudioPlayer(source: audioSource)
    self.addAudioPlayer(audioPlayer)

This is not ideal as it fills the audioPlayers array everytime I play a new sound. Ideally, I could have one SCNAudioPlayer for each sound that I want to play and just call a "play" function to play it back.

Unfortunately, I could not find a play function. What also irritates me, is that SCNAudioPlayer automatically plays the sound when added to a node. But I want to set up my whole scene without any sounds playing back and then at a later point of time, play the sounds.

What is the correct way of using SceneKit's Audio Engine?

like image 946
Max Avatar asked Jul 29 '15 12:07

Max


2 Answers

You can use the action as was previously answered, as it is syntactically simpler to use.

SCNAudioPlayers are recycled by the engine so you do not need to be concerned about their lifespan unless you need to modify them while they're playing. The idea behind the SceneKit audio engine is that sounds should behave in the same way that SCNNodes do. If a node is in the scene graph then it is visible and so are its geometry, particle systems, etc. So if a sound is attached to a node it should start playing right away if the node is visible (and stop if it is hidden).

The audio source only represents the actual audio data. Think of it as of a texture: it is loaded once and can be referenced by a number of materials on a number of 3d nodes. The audio player instantiates the audio source so that you can play it on multiple nodes at the same time, just like you would use the same material for different geometries on different nodes.

Hope this helps and give some perspective on the design choices,

S.

like image 196
Sebastien Metrot Avatar answered Oct 07 '22 10:10

Sebastien Metrot


For playing a single sound as/if when hit or otherwise instigated by an event and/or input...

There's a special "action": SCNAction.playAudioSource

class func playAudioSource(_ source: SCNAudioSource,
     waitForCompletion wait: Bool) -> SCNAction

Then, to play the sound, run it on a node:

myNode.runAction(myActionName)
like image 29
Confused Avatar answered Oct 07 '22 08:10

Confused