Add existing Script in Runtime

Hi I’m new here can i add existing script add on entity in runtime?. Your help would be highly appreciated for me

Hi regeme, there is some documentation in the user manual for that. Creating new scripts | Learn PlayCanvas

3 Likes

This tutorial your reference describes how to add a new script it uses the create function.
But what @regeme would like to know and what I am also struggling to find is a way to add an already existing script from the assetRegistry to a new entity - Thats how I understood it anyway and its the issue I’m currently facing.

I have this but it doesn’t work:

let boundingsBoxScript =  this.app.assets.find("boundingBoxShape.js", "script");
console.log(boundingsBoxScript.resource);
gameField.addComponent('script',{scripts: [boundingsBoxScript.resource]});

from the log I’m getting an object with attribute scriptType in it so I assume it works or is loaded
but its not being added to the entity (gameField) I think - or if it is added it is not calling the initialize function which would be weird also

Ηι @Dinkelborg,

What you need to first is to load the script asset, that way it gets automatically added to the script registry. From there you can use script.create() to add an instance to a script component.

const boundingsBoxScript =  this.app.assets.find("boundingBoxShape.js", "script");

// we wait for the asset to load and get added to the registry
boundingsBoxScript.ready( () => {
   gameField.addCompoent('script');
   gameField.script.create('boundingBoxShape');
});

this.app.assets.load(boundingsBoxScript);

Okay I thought load was only for assets that have preload disabled
[EDIT]
And additionally: you’re also using the create function again … from what I can see in the api docs this will create a new script and the parameter you’re passing to it will just be the scripts name

Hi @Dinkelborg I think the linked section of the documentation Adding a script component at run time is referring to an already loaded script. it says

" Note, that the “rotate” script should already have been loaded at this point. You can load a script using the Asset Registry’s load() method."

So if you’ve already preloaded your script you should be able to use the example as in the documentation.

1 Like

I just replaced the code I had above with the following:

let boundingBoxScript =  this.app.assets.find("boundingBoxShape.js", "script");
gameField.addComponent('script');
gameField.script.create('boundingBoxShape',{ attributes: {halfExtents: new pc.Vec3(0.5,0.5,0.5)}});

Which works - I am not previously loading the script by hand
in the editor you have an option on all your assets (so scripts too) there is a checkbox called Preload
and afaik (which doesn’t mean a lot as its been a few years since I coded here last) as long as Preload
is on the asset will be loaded automatically and it is not necessary to use the app.assets.load function

[EDIT]

But what I don’t get is why it didn’t work with the addComponent function then - look at the code I had before - according to the api docs it looks like you can pass an array of scripts as an optional argument when using the addComponent function for adding a script component - which would make sense as in the editor the script component is a holder for an array of script assets.
So far so good but when I was trying to pass my script to it nothing happened - also no error message btw …
So what was going on there? Could it be a bug or would I have to had created the script in some way using the create function first to then pass that instace of the script in the addComponent function?

Even better … Sorry for making a new reply for this, but I already edited the above one and … well this seems to be the final solution to this so: It seems you can skip the assets.find part all together - the script is for some reason already loaded and ready (probably because of the preload setting) so the only code necessary to add an already existing script is:

yourEntityName.addComponent('script');
yourEntityName.script.create('yourScriptName',{ attributes: { yourAttributes: "yourAttributesDefaultValues"});
1 Like