Dynamic creation of sound objects

Basically what I’m trying to do is create a script to handles all my sounds in game. So if I ever want to play a sound that I have in my asset I just call:

SoundManager.play2D("someAwesomeSound", _volume, _loop)`

and this script creates an entity with audiosource sets up everything and plays the sound. First thing I found out that I cant access the 3d attribute to switch between 2D/3D sounds like this in script:

entity.audiosource.3d = false;

well maybe I can access it but the browser throws “Unexpected token ILLEGAL” syntax error I think it doesnt like the 3 at the begining XD

I somehow worked around that but now when I got everything set up somehow it still doesn’t play the sound

createSoundObject: function(name, position){
        if (!name){
            name = "Sound"+activeSounds.lenght;
        }
        if (!position){
            position = pc.Vec3.ZERO;
        }
        var retval = template2D.clone();
        retval.name = name;
        retval.setPosition(position);
        
        soundsParent.addChild(retval);
        
        return retval;
    },
    
    play2Dsound:function(sound, volume, loop){
        if (!volume){
            volume = 1;
        }
        if (!loop){
            loop = false;
        }
        var entity = this.createSoundObject(sound,pc.Vec3.ZERO);
        
        var asset = app.assets.find(sound);
        if (asset){
            entity.audiosource.assets = asset.resource;
        }
        else {
            console.error("Can't find asset named: " + sound);
            return false;
        }
        entity.audiosource.chanel = pc.extend.Chanel1;
        
        entity.audiosource.activate = true;
        
        entity.audiosource.volume = volume;
        entity.audiosource.loop = loop;
        
        activeSounds[sound] = entity;
        
        entity.audiosource.play(sound);
        
        return true;
    },

The template2D is basically an entity set up for a 2D sound(empty entity with audiosource component with 3d set to false). I’m kind of lost what did I do wrong. Anyone tried something like this before an can offer some advice?

So I looked at the assettutorial and updated my script because it seemed I was doing “stuff” the wrong way.
I added an attribute which holds my sound assets:

pc.script.attribute("sounds", "asset", [], {type: "audio"});

And I replaced the line where I load the asset from:

var asset = app.assets.find(sound);

with:

var asset = app.assets.getAssetByResourceId(this.sounds[index]);

But I still cant get the sound to play.

I haven’t had to time to test properly but quick look, does this need to be an array?

As far as I have tested the attribute assets of audiosource component is an array even though you can’t add more then one element to it even in editor. As for the resource attribute of asset that is not an array. If I remember right I did some testing where I added the resource as an array but that did not help.

I think I got it to work at some point when I did something with the chanel attribute of audiosource component but I don’t remember what it was or if it even was because of the chanel now when I debug it the chanel is always undefined.
The pc.extend.Chanel1 i got from debbuging of a working entity that I manualy set up in editor and than I checked its channel attribute value in chrome debugger so I have no ideal if it is even correct or relevant…

You can definitely add multiple audio files to a single audiosource component.

Here is a simple script which takes a list of asset resources:

pc.script.attribute("files", "asset", [], {type: "audio"});

pc.script.create('play', function (context) {
    // Creates a new Play instance
    var Play = function (entity) {
        this.entity = entity;
    };

    Play.prototype = {
        // Called once after all resources are loaded and before the first update
        initialize: function () {
            // this.entity.audiosource.play("alone_theme");
            // var channel = this.entity.audiosource.channel;
            
            this.entity.addComponent("audiosource", {
                loop: true,
                assets: this.files
            });
            
            this.entity.audiosource.play("alone_theme");
        },

        // Called every frame, dt is time in seconds since last update
        update: function (dt) {
        }
    };

    return Play;
});

Looking at your code:

entity.audiosource.assets takes a list of asset ids (Numbers)

Also you can access the 3d property using array access style: e.g. entity.audiosource['3d'] = true

Hope that helps.

Thanks dave,

sorry for late response had other stuff to do so couldn’t test it, but it worked fine after I used the ids.
Didn’t know about the array access i’m learning Javascript on the fly as I try to do stuff so thanks for pointing it out.