User Manual

Communication

Events are a useful way of communicating between scripts in order to respond to things that happen without checking every frame.

The PlayCanvas Engine contains a simple way to add event handling to any object:

pc.events.attach(object);

This will add the methods: on(), off(), fire() and hasEvent() to the object. Which means that you can listen for events fired by that object.

By default all script instances can fire events you don't need to call this manually.

Using events

Trigger an event using fire(). In this example, the player script fires a move event every frame with the x and y values passed as arguments.

var Player = pc.createScript('player');

Player.prototype.update = function (dt) {
    var x = 1;
    var y = 1;
    this.fire('move', x, y);
};

Listen for events firing by using on() and off(). In this example, the display script listens for the move event on the player and prints out the x and y values.

var Display = pc.createScript('display');

// set up an entity reference for the player entity
Display.attributes.add('playerEntity', { type: 'entity' });

Display.prototype.initialize = function () {
    // method to call when player moves
    var onPlayerMove = function(x, y) {
        console.log(x, y);
    };

    // listen for the player move event
    this.playerEntity.script.player.on('move', onPlayerMove);

    // remove player move event listeners when script destroyed
    this.playerEntity.script.player.on('destroy', function() {
        this.playerEntity.script.player.app.off('move', onPlayerMove);
    });
};

Application Events

There is a very convenient and powerful method of using events to communicate between entities that we call "Application Events". As you can see in the example above listening for events on specific entities incurs some set up cost. For instance, the listener must have a reference to the specific entity that is firing the event. This works with some cases, but for a more general case we find that it is more appropriate to use the main application (this.app) as a central hub for firing events. This means you don't have to keep references of entities around in order to use the events.

This works by firing and listening to all events on this.app. By convention we use namespaces in event names in order to signal event scope and prevent clashes. For example, the player:move event is fired on the application instead of firing the move event on the player.

Let's try the same example using application events.

Firing the player:move event.

var Player = pc.createScript('player');

Player.prototype.update = function (dt) {
    var x = 1;
    var y = 1;
    this.app.fire('player:move', x, y);
};

Listening for the player:move event.

var Display = pc.createScript('display');

Display.prototype.initialize = function () {
    // method to call when player moves
    var onPlayerMove = function(x, y) {
        console.log(x, y);
    };

    // listen for the player:move event
    this.app.on('player:move', onPlayerMove);

    // remove player:move event listeners when script destroyed
    this.on('destroy', function() {
        this.app.off('player:move', onPlayerMove);
    });
};

As you can see this reduces set up code and makes for cleaner code.

More details on events in the API Reference