Cannot call a function from a diffrent entity (this.app undefined)

Hi there, today’s my first day on playcanvas and I’ve been trying to change the material of an FBX object using a button.
There’s a script in the button (green.js) that calls to a function in the script of the object (colorizer.js) which would change it’s material.

But the problem is that i used var Bottle = this.app.root.findByName("bottle"); in the green.js and it shows up an error saying TypeError: this.app is undefined

Here’s the link to my project:
https://playcanvas.com/project/709268/overview/bottlestyler

I was actually following the post (App.root does not give me root?) but it did not work for me.

What am I missing? How should I apply a solution to this error?

Hi @navinzero and welcome,

So, this.app is only valid inside a script method. You can fix this error by declaring your Bottle variable inside the initialize() method:

// initialize code called once per entity
Green.prototype.initialize = function() {
    
   //find the "bottle" entity and take it into the bottle variable
   this.Bottle = this.app.root.findByName("bottle");
};

You will notice that instead of var, I’ve saved the value to a property. The reason is to be able to use it in your onPress method, like this:

//what to do after detecting the click
Green.prototype.onPress = function () {  
    
    //trying to activate the function green() in the colorize.js to change the colour of the bottle
    this.Bottle.script.colorizer.green();
    console.log("Bottle");
  
};
1 Like

Wow! Thanks Leonidas! I didnt know that this.app is only valid inside a script method. The previous errors were cleared thanks to you solution.

But now, it shows up an error saying TypeError: this.Bottle is undefined. I have double checked the code but according to my knowledge I couldnt find any logical issues in this. Why did this happen even after initializing it?

Here’s updated code with your amazing suggestions:

var Green = pc.createScript('green');

// initialize code called once per entity
Green.prototype.initialize = function() {
    
    //find the "bottle" entity and take it into the bottle variable
    this.Bottle = this.app.root.findByName("bottle");
    
};

//detects the click
Green.prototype.initialize = function() {
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onPress, this);
};

//what to do after detecting the click
Green.prototype.onPress = function () {  
    
    //trying to activate the function green() in the colorize.js to change the colour of the bottle
    this.Bottle.script.colorizer.green();
    console.log("Bottle");
  
};

In the Scene Editor, I would double check the Entity name. If you still having trouble, please post a link to the project.

1 Like

Thanks for replying yaustar. As I checked the entity names are fine…
here’s the link to the https://playcanvas.com/project/709268/overview/bottlestyler

Looks like a copy of issues here:

It looks like you haven’t saved the file yet (it’s still yellow here which means it hasn’t saved yet)

On the Green.js script, you have created two initialize functions

The second initialize function basically overrides the first so the code:

    this.Bottle = this.app.root.findByName("bottle");

Is never executed.

The fix is to only define the initialize function once and have both the find and the button callback setup there:

var Green = pc.createScript('green');

// initialize code called once per entity
Green.prototype.initialize = function() {
    this.Bottle = this.app.root.findByName("bottle");
    this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onPress, this);
};

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

//what to do after detecting the click
Green.prototype.onPress = function () {  
    //trying to activate the function green() in the colorize.js to change the colour of the bottle
    this.Bottle.script.colorizer.green();
    console.log("Bottle");
};
2 Likes

Thanks @yaustar !
I thought yellow coloured green.js was indicating that it has some errors. Didn’t know it wasn’t saved and that the second initialize function overrides the first.

It finally worked! the bottle changes the colour on click!