Is there a way to call a playcanvas method from a node js method?

If I am self-hosting in both apps (node and playcanvas), is there a way to call a canvas method even if my playcanvas app is not hosted?

I know that you can call a playcanvas method with postMessage but, I’ve seen it only in hosted apps. Sorry for my misspelling.

Depends how you have it all hooked. If the PlayCanvas app is in an iframe, regardless if you are self hosting or are hosting elsewhere, you can use postMessage.

If it’s on the same page, the pc object should be accessible in the global scope. You can then call pc.Application.getApplication() to get the current PlayCanvas app and access everything you need there.

1 Like

Hi @Axel_Saucedo,

If your node.js instance is running on the server and Playcanvas client-side you will have to use another means of communication, like web sockets.

There is a tutorial on this here:

https://developer.playcanvas.com/en/tutorials/real-time-multiplayer/

You can also expose functions directly to the global scope with this code. I use it a fair amount for my Vue.JS app, it’s the same as going through pc.app.root.findByName('entity name').script.scriptName.yourFunction(), just a little more convenient.

In your PlayCanvas script:

// Global function
window.yourFunction = function (x, y, z) {
    var app = pc.Application.getApplication();
    var entity = app.root.findByName("Name of Script Entity");
    entity.script.scriptName.yourFunction(x, y, z);
};
// Script function
scriptName.prototype.yourFunction = function(x, y, z) {
    return x + y + z;
};

EDIT - USE PLAYCANVAS EVENTS INSTEAD
Since posting this I’ve looked more into switching to PlayCanvas events. I’m now convinced that’s the best approach, both in terms of ease-of-use and best practices. I’ve since switched to using PlayCanvas events in my projects, I don’t want to leave this post here with bad information. Implementing events was easier than expected and your code looks cleaner too.

To use PlayCanvas events do this instead:
In your PlayCanvas script:

scriptName.prototype.initialize = function() {
    this.app.on('creativeEventName', this.yourFunction, this);
};
// Script function
scriptName.prototype.yourFunction = function(x, y, z) {
    return x + y + z;
};

From another PlayCanvas script:

this.app.fire('creativeEventName', x, y, z);

From any JS script:

pc.Application.getApplication().app.fire('creativeEventName', x, y, z);
1 Like

I tried this pc.app.root.findByName('FirstPersonMovement').script.firstPersonMovement.setScore(); but it didn’t work.

Now, I downloaded the project and I’m trying to call a function inside the main index.html.

<script src="__modules__.js"></script>
<script src="__start__.js"></script>
<script src="__loading__.js"></script>
<script>
    pc.app.root.findByName('FirstPersonMovement').script.firstPersonMovement.setScore();
</script>

Method inside the playcanvas project:

var FirstPersonMovement = pc.createScript('firstPersonMovement');

FirstPersonMovement.prototype.setScore = function () {
  alert("Entro");  
};

Hi @Axel_Saucedo,

Your last <script> element will execute the containing Javascript immediately. Meaning way before the Playcanvas app initializes, the scene hierarchy loaded and everything is set.

You will have to communicate from inside Playcanvas, that the script is ready and can be called.

You can do something like this:

<script>
   window.pcReady = function(){
      // we know Playcanvas is ready, now we can call methods
      pc.app.root.findByName('FirstPersonMovement').script.firstPersonMovement.setScore();
   };
</script>

And in one of your scripts, call this:

var FirstPersonMovement = pc.createScript('firstPersonMovement');

FirstPersonMovement.prototype.initialize = function () {
   window.pcReady();
};

FirstPersonMovement.prototype.setScore = function () {
  alert("Entro");  
};

Surely there are more elegant ways to do this, like using postMessage, but this will work as well.

1 Like

It’s possible to listen for the first postrender event and do the logic in the callback (on my phone so can’t look for the exact name of the event).

What error message did you get?