timetocode Posted December 2, 2018 Share Posted December 2, 2018 Hello there. What is intended method of playing the same sound multiple times *concurrently* without re-downloading the sound file from the server? const gunshot = new BABYLON.Sound('foo', "sounds/gun_semi_etc.wav", scene, null, { volume: 1 }) If I have multiple players or bots in my game, any of them can produce gunfire. As each of them shoots, I end up with a separate web request per entity: I'm accustomed to howler, where the first time a sound is created, like 'foo.wav' it will load it from the server. Any subsequent sound objects created that play 'foo.wav' will build themselves from the same sound data without an xhr. How do I accomplish the equivalent? TY TY Quote Link to comment Share on other sites More sharing options...
Raggar Posted December 2, 2018 Share Posted December 2, 2018 I use the AssetsManager to load all my sounds, and put them into an array at predictable indexes. This way, I can clone the sounds and attach them to all players. /////Task var gunshotSound3 = assetsManager.addBinaryFileTask("soundTask3", "sounds/gs3.ogg"); /////onSuccess callback gunshotSound3.onSuccess = function (task){ var gs3 = new BABYLON.Sound("gunshotSound3", task.data, scene, null, { loop: false, autoplay: false, spatialSound: true }); sounds[2] = gs3; gs3.setVolume(0.6); } /////Player creation function player(gunIndex, ..., ..., ...){ ///gunIndex = 2; ... ...... ... ... this.gunSound = sounds[gunIndex].clone("gunSound"); this.gunSound.attachToMesh(this.mesh); } /////Gunshot sound needed player.gunSound.play(); /////New weapon etc. player.gunSound.dispose(); player.gunSound = null; player.gunSound = sounds[x].clone("gunSound"); QuintusHegie and timetocode 2 Quote Link to comment Share on other sites More sharing options...
timetocode Posted December 2, 2018 Author Share Posted December 2, 2018 Thanks Raggar that looks good! I wonder if anyone would be interested in having this behavior added to the api. Or maybe just tacked on by including a file. The following is all pseudo code, but I will probably implement it for real on Monday. Usage: BABYLON.SoundAtlas.add('filename.ext') // etc for all sounds BABYLON.SoundAtlas.load(scene, callback) // starts loading // using a sound from the atlas, while mimicking the original BJS api const gunshot = BABYLON.Sound.FromAtlas('gunshot', 'filename.ext', scene, { volume: 1 }) Possible extension to babylon Sound: BABYLON.Sound.prototype.FromAtlas = (name, filepath, scene, options) => { const cachedSound = BABYLON.SoundAtlas.get(filepath) if (!cachedSound) { throw new Error('Sound not found in SoundAtlas') } const sound = cachedSound.clone() sound.name = name sound.updateOptions(options) // autoplay won't work without some minor modification } Presumably would not work with multiple scenes. Everything I've made is all single scene with programmatically spawned meshes, so I'm not sure what would have to change. Sound atlas: /* Sound Atlas */ const BABYLON = require('babylonjs') const basePath = './sounds/' // should be modifiable instead const sounds = new Map() const soundFilenames = [] const queueSounds = (assetsManager, scene) => { soundFilenames.forEach(soundFilename => { const path = `${basePath}` const name = `${basePath}${soundFileName}` const binaryTask = assetsManager.addBinaryFileTask(name '', path, soundFilename) binaryTask.onSuccess = (task) => { const sound = new BABYLON.Sound(task.name, task.data, scene, null, {}) sounds.set(task.name, sound) } }) } const add = (soundFilename) => { soundFilenames.push(soundFilename) } const load = (scene, cb) => { const assetsManager = new BABYLON.AssetsManager(scene) queueSounds(assetsManager, scene) assetsManager.onFinish = () => { cb() } assetsManager.onTaskError = (task) => { console.log('error loading task', task) } assetsManager.load() } module.exports.add = add module.exports.load = load Haven't tried it yet, but that's the gist of it. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.