Hi folks.
I’m working on a first person sim, which includes an object heirarchy like this to represent the player:
Object3D: playerCage (For rotating camera left and right and moving player)
Mesh: player mesh (For rendering player when in 3rd person mode)
Camera: thirdPersonCamera
Object3D: pitchCage (For rotating camera up and down)
Camera: firstPersonCamera
AudioListener: audioListener
Object3D: stepSoundCage (for containing footstep sounds)
PositionalAudio: footstepSound01
PositionalAudio: footstepSound02
PositionalAudio: footstepSound03
PositionalAudio: footstepSound04
PositionalAudio: footstepSound05
Its working well in my sim architecture, but for some reason, the footstep sounds always seem to originate from world position 0, 0, 0. That is to say, once the game begins, as the player walks forward, the volume of the footsteps diminishes. This is contraray to what I’d expect - for the volume to remain constant - as the distance between the audioListener, camera, and footstep sounds is always 0, thanks to the nesting.
I’ve also tried logging world positions in the render loop to debug this, but have found this to be the case:
camera.getWorldPosition().z === audioListener.getWorldPosition().z === playerCage.getWorldPosition().z // true
I’ve tried a bunch of different things to try and fix this but am starting to get a bit desparate. What I’d like to ask is: Are there any gotchas to be aware of when using positional audio that could cause this type of behaviour?
Heres a whistle-stop tour of how I’m leveraging the positional audio objects:
// Create the audio listener
const audioListener = new Three.AudioListener();
// Create a media manager and tell it to load all assets
const mediaManager = new MediaManager({
baseUrl,
assetList, // Array of string paths
audioListener,
});
const { succeeded: succeededAssets, failed: failedAssets } = await mediaManager.load();
// Inside the media manager, convert URLs to PositionalAudio objects
return new Promise((resolve, reject) => {
const loader = new Three.AudioLoader();
loader.load(
this.src,
audioBuffer => {
const sound = new Three.PositionalAudio(this.audioListener);
sound.setBuffer(audioBuffer);
this.asset = sound;
this.loaded = true;
resolve();
},
() => {},
() => {
this.loaded = false;
reject();
},
);
});
// In the player object, create the heirarchy shown above
// Add sounds to stepSoundCage
// Add stepSoundCage to playerCage
// Add audioListener to playerCage
// Add player object to scene
I’ve noted that
- All assets load successfully
- I’ve ensured the app only starts up after a user gesture
- No errors in the console