Uplink001
Uplink001

Reputation: 69

SceneKit: positional audio won't work

I'm trying to get SceneKit to play a footstep sound everytime one of my characters moves. As they get closer (to the player), the audio should rise in volume.

This is how I setup my audio source:

private lazy var stepAudioSource:SCNAudioSource = {
    let tempAudioSource = SCNAudioSource(fileNamed: "art.scnassets/Audio/step_enemy.wav")!
    tempAudioSource.volume = 0.3
    tempAudioSource.rate = 0.1
    tempAudioSource.loops = true
    tempAudioSource.shouldStream = false
    tempAudioSource.isPositional = true

    return tempAudioSource
}()

To play the audio at first I tried using playAudioSource, giving a key to the action and trying to removing it each time the character stop. Unfortunately, even removing the action didn't seem to stop the audio playback so I did this instead:

private var isWalking:Bool = false {
    didSet{
        if oldValue != isWalking {
            if isWalking{
                addAnimation(runAnimation, forKey: "run")

                    let sfxPlayer = SCNAudioPlayer(source: stepAudioSource)
                    characterNode.addAudioPlayer(sfxPlayer)
            }else{
                removeAnimation(forKey: "run", blendOutDuration: 0.2)

                removeAllAudioPlayers()
            }
        }
    }
}

Audio files are mono as I discovered positional audio won't work with dual-channel audio. shouldStream property is set to false.

This does work most of the times. Unfortunately if the node starts too far from the player the footstep audio won't start playing and when they actually get close no sound will be heard. What am I doing wrong?

Upvotes: 2

Views: 713

Answers (1)

Andy Jazz
Andy Jazz

Reputation: 58053

Try this way:

let tempAudioSource = SCNAudioSource(fileNamed: "art.scnassets/Audio/step_enemy.wav")!
tempAudioSource.volume = 0.3
tempAudioSource.rate = 0.1
tempAudioSource.loops = true
tempAudioSource.isPositional = true
tempAudioSource.shouldStream = false
tempAudioSource.load()            //loads audio data and prepares it for playing...
let player = SCNAudioPlayer(source: tempAudioSource)  
whatEverNode.addAudioPlayer(player)

And don't forget about audio listener node – the node representing the listener’s position in the scene for use with positional audio effects.

var audioListener: SCNNode? { get set }

Upvotes: 2

Related Questions