[SOLVED] One script to control multiple buttons?

I have a dozen buttons in my project, each one will fire a function that makes a disabled entity (PD which is in the 2D Screen) visible by enabling it.

So far no luck, this is my attempt at getting one button to work:

var ProductButtons = pc.createScript('ProductButtons');

// initialize code called once per entity
ProductButtons.prototype.initialize = function() {
    
var Hyd_P1 = this.app.root.findByName('Hyd_P1');
   Hyd_P1.element.on('mouseup', function()   {
      this.app.root.findByName('PD').enabled = true;
   }, this); 

};

// update code called every frame
ProductButtons.prototype.update = function(dt) {
   
};

I intend this code to act like a loaded global script, not attached to any entity, just listening for which button is clicked and fire its function. Something tells me I’m going about it all wrong, this must be possible, right?

Grateful for any help, thanks!

There a number of ways you could do this depending on your scenario.

The code that you have written should work for the one button though, are you getting any errors? Can you share the project?

No errors…

The big red square will be a product display area, left active for testing. Clicking on a main category will hide it, but when a product button is clicked, I want it to be enabled; visible and display various information hopefully from the same button function that includes enabling it.

Right now Product 1 under Hydraulics is what I wrote the code for so far.

I’m evaluating this platform for a company I work for.

Thanks!

https://launch.playcanvas.com/1044840?debug=true

It looks like the pc.script hasn’t been attached to an entity so no instance of the pc.script is created. Was that the intention?

Are you trying to create a ‘global’ script that doesn’t need to be attached to an Entity?

That is correct, the script is in the loading order queue and its Preload checkbox is checked so I assumed that meant it was being loaded at runtime.

Does it need to be attached to an element?

I attached it to the Menu entity (2D Screen) still nothing…

This is a mystery.

Thanks!

I thought for sure this would sort it out, but it didn’t.

I declared the PD as a defined variable:

var ProductButtons = pc.createScript('ProductButtons');

// initialize code called once per entity
ProductButtons.prototype.initialize = function() {
    
var Hyd_P1 = this.app.root.findByName('Hyd_P1');
var PD = this.app.root.findByName('PD');
    
   Hyd_P1.element.on('mouseup', function()   {
      PD.enabled = true;
   }, this); 

};

// update code called every frame
ProductButtons.prototype.update = function(dt) {
   
};

Which would streamline the code a little, if it worked.

I intend to do an update to the documentation to hopeful better explain this but here’s the TLDR version.

var ProductButtons = pc.createScript('ProductButtons');

It is being loaded at runtime but what the code does is create a pc.ScriptType object with a name to the engine’s script registry (in this case ProductButtons). None of the pc.ScriptType functions like initialise or update are being called.

In this case, the initialize function is not called unless the pc.ScriptType is added to an Entity and the Entity needs to be enabled.

For scene manager scripts like this, typically these are added to the scene root object.

The issue is that the script was changed from:

var ProductButtons = pc.createScript('productButtons');

to

var ProductButtons = pc.createScript('ProductButtons');

At some point and because the name of the pc.ScriptType had changed (it’s case sensitive), you need to reparse the script to update the script registry in the Editor:

After the parse, you will notice the red ! next to script entry on the Entity Menu. This is because it can’t find the pc.ScriptType ‘productButtons’ anymore since it was renamed to ‘ProductButtons’

You will need to remove it and add ‘ProductButtons’
image

And it should now work.

Alternatively, you can go back to the script and change it from:

var ProductButtons = pc.createScript('ProductButtons');

to

var ProductButtons = pc.createScript('productButtons');

And that would also work.

1 Like

On a separate note, you may want to consider a different setup that would allow you data drive this in the Editor, rather than manually typing all the Entity names out and registering the event callbacks for every button in the app.

Thanks again, that worked!

I hadn’t thought of attaching it to the root, now I know that’s possible.

Is there some documentation or something that demonstrates this ‘data drive’ concept?

That sounds very useful, thanks for your help!

Have you used script attributes yet?

Is script attributes similar to declaring a public variable that will show up in the editor interface as an option to modify?

I haven’t used that at all yet.

Thanks!

Yes, it be a good thing to try as it allows you to enter data in the Editor and reference other Entities directly instead of using the slow findByName function.

https://developer.playcanvas.com/en/user-manual/scripting/script-attributes/

1 Like