I saw your example on how to communicate with external scripts. Is there a way to create custom events apart from “loadingStarted” “loadingProgress” and “loadingFinished” which other systems on the website can listen to? E.g. I wanna click a button in needle and some div element on the website should change color.
Already tried something like this but does not seem to work.
public activateOverlay(_overlayID : string = "")
{
console.log("Func fired");
this.context.domElement.dispatchEvent(new CustomEvent("activateOverlay", {
detail: {
id: _overlayID
}
}));
}
index.html
<needle-engine myFunction="activateOverlay"></needle-engine>
<script>
function myFunction(id) {
console.log("I'm alive!");
}
</script>
Original Post on Discord
by user 334342083445784576
You dont need to subscribe to it via the html element.
Multiple options:
Make your event static / your type accessible statically
export class MyComponent extends Behaviour {
static get Instance() { return this._instance }
static _instance? : MyComponent;
awake() { MyComponent._instance = this; }
and then import it in your script (make sure its a module)
import { MyComponent } from "your/package"
Alternatively get the context from the engine-element (see docs)
and then query for the component you are interested in:
async function init() {
const ctx = await engine_component.getContext();
const myComponentInstances = GameObject.findObjectsOfType(MyComponent, ctx)
// do what you need
Hmm, calling the “activateOverlay” function in the needle script from the external script works (line 12), but when I’m calling “activateOverlay” from the UnityButton, “onOverlayActivated” is not defined. I’m missing something.
by user 334342083445784576
Not sure what you sent there - can you copy the code here?
I assuem its a bind
issue
Sorry, had to figure out how to format here. Now It’s looking readable 
Needle Script
import { Behaviour, serializable } from "@needle-tools/engine";
export class NeedleActivateOverlay extends Behaviour {
public onOverlayActivated?: (string) => void
public activateOverlay(_overlayID : string = "")
{
console.log("Regt mich auf!");
if (!this.onOverlayActivated)
{
console.log("onOverlayActivated not defined");
return
}
this.onOverlayActivated(_overlayID);
}
}
external Script
import { GameObject } from "@needle-tools/engine";
import { NeedleActivateOverlay } from "./scripts/NeedleActivateOverlay";
const ctx = await document.querySelector("needle-engine")?.getContext()
const myComponentInstance = GameObject.findObjectOfType(NeedleActivateOverlay, ctx)
myComponentInstance.onOverlayActivated = MyCustomFunction;
function MyCustomFunction(id : string) {
console.log("Es hat geklappt " + id);
}
myComponentInstance?.activateOverlay("Test");
by user 334342083445784576
the last line in the external script works, but pressing a button with this function is not
by user 334342083445784576
“Es hat geklappt Test”
Pressing the Unity Button, it prints
“onOverlayActivated not defined”
by user 334342083445784576
What does it print when you log console.log(this)
in activateOverlay
okay sorry for bothering.
I just found out there are multiple instances of this script in my scene 
by user 334342083445784576
Works like a charm now!
const myComponentInstances = GameObject.findObjectsOfType(NeedleActivateOverlay, ctx)
for (let i = 0; i < myComponentInstances.length; i++) {
myComponentInstances[i].onOverlayActivated = MyCustomFunction;
}
function MyCustomFunction(id : string) {
console.log("Es hat geklappt " + id);
}
by user 334342083445784576
Javascript 
by user 334342083445784576