It's really common to want one script to talk to another script. Sometimes that other script isn't even on the same object as the original script. You can accomplish this using a couple different approaches.
When you "Send an Event" in dot big bang you are calling a method by name in scripts on an object and supplying optional arguments to it. The receiving script could be the same script that sends the event but it is usually a separate one. You can either use the Entity.sendEvent()
or Game.sendEventToTag()
method to do this.
Contents
In order to send an event to an Entity you need three things:
If you want to send an event within the same Entity that the sending script exists on you can easily do that by using this.entity
as your Entity reference.
Script 1
start() {
// Send the event.
this.entity.sendEvent("myMethod", 42);
}
Script 2
// Called by Script 1.
myMethod(myNumber: number) {
console.log(`I was called with the number ${myNumber}!`);
}
In order to send an event to a script on a different Entity you will need a reference to that Entity. There are several ways you could get this reference. The most straight-forward approach is to store a reference to the Entity in an EntityRef
property.
Script 1
// A reference to another Entity. Set this in the Entity Panel.
entityRef = new EntityRef();
start() {
// Make sure a reference to an Entity has been set!
if (!this.entityRef.exists()) {
return;
}
// Retrieve the Entity from the reference. We know it exists so we use ! to tell the compiler it can't be null.
const entity = this.entityRef.get()!;
// Send the event.
entity.sendEvent("myMethod", 42);
}
Script 2
// Called by Script 1.
myMethod(myNumber: number) {
console.log(`I was called with the number ${myNumber}!`);
}
Remember that every script on the receiving Entry will have the event method called if it exists. Each script with a matching method name will have that method called, which can be very useful!
There is no guaranteed order that the scripts will call the methods in.
Even though it takes some additional set up, sendEventToTag()
can be easier to use than sendEvent()
because you don't need an explicit Entity reference to use it. You can send off the event, and any Entities that have a matching tag on them will call that event in all of their scripts.
Make sure that the Entities that contain "Script 2" have the tag "tagName" on them.
Script 1
start() {
// Send the event.
this.game.sendEventToTag("tagName", "myMethod", 42);
}
Script 2
// Called by Script 1.
myMethod(myNumber: number) {
console.log(`I was called with the number ${myNumber}!`);
}
In a lot of cases when you send an event you want to get a response back with some data. This can be done in several ways which are outlined in the following examples.
Unfortunately Types are not maintained between scripts so you should make sure you validate everything and ensure you are working with the data you expect. The examples below are not validating anything in order to be as brief as possible.
These examples will work with both sendEvent()
and sendEventToTag()
, though you need to be aware that if multiple scripts run the event your result or callback will be modified or called multiple times.
The recommended approach is to pass an object reference that will be modified by the second script. This approach is the most performant since it doesn't call any additional functions and just alters an object in place.
Script 1
start() {
// Create the result object.
const result = {
myNumber: 0
};
// Send the event.
this.entity.sendEvent("myMethod", result);
// Log out the result.
console.log(`My result is: ${result.myNumber}!`);
}
Script 2
// Called by Script 1.
myMethod(result: any) {
result.myNumber = 42;
}
Another approach is to pass a function that will be called by the second script. While it does add an additional function call, it might make more sense in the context of your script to use this approach.
Script 1
start() {
// Send the event.
this.entity.sendEvent("myMethod", (myNumber: number) => {
// Log out the result.
console.log(`My result is: ${myNumber}!`);
});
}
Script 2
// Called by Script 1.
myMethod(callback: Function) {
// Pass the result into the callback.
callback(42);
}