Make function static/accessible from Javascript side outside of Needle?

I have a controller script with a function that I need to be accessible from javascript outside of the Needle build - this class has a few instances in the build but I only want it to be accessed from one instance from outside of Needle. E.g. a button pressed in HTML calls the function directly.

Is there a simple example of how to do this?

Original Post on Discord

by user 103054507105067008

a controller script = a component? You can just make a static getter and import it from anywhere in your js code elsewhere.

I created a sample for you a few months ago pretty much exactly about this, remember? :slightly_smiling_face: it’s still in the samples repository/samples package

Found it thanks

by user 103054507105067008

As there are multiple instances of this script, I might make another script that there is only one of which has the static getter with a reference to just the controller script I wanted to send events to.

by user 103054507105067008

Yep sorry a controller script like a main script that has most of the interactive experience logic in it

by user 103054507105067008

logically it’s the same as you’d do it in C#

and syntax wise almost the same too

In the example you have ```
// this method is exported inside the package.json main file
export function myJsInteropMethod() {
showBalloonMessage(“Hello, im a message inside a npm package”)
}


which is outside of the class so I can't reference a variable in the class above it called MyJsInteropSampleComponent, how do I reference variables in the class from outside it there?

*by user 103054507105067008*

E.g. I am trying to do this

import {
  Behaviour,
  serializable,
  showBalloonMessage,
} from "@needle-tools/engine";
import { MouseIncrementRotate } from "./MouseIncrementRotate";

export class StaticEvents extends Behaviour {
  @serializable(MouseIncrementRotate)
  //@ts-ignore
  public mainRotScript: MouseIncrementRotate;

 
  static get instance() {
    return this._instance;
  }
  private static _instance: StaticEvents;

  constructor() {
    super();
    StaticEvents._instance = this;
  }
}

export function openHotspot(hotsptId: number) {
    mainRotScript.openHotspot(hotsptId);
}

// this method is exported inside the package.json main file
export function myJsInteropMethod() {
  showBalloonMessage("Hello, im a message inside a npm package");
}

by user 103054507105067008

Just do import{ StaticEvent } from "path/to/your/package/or/script"

and then use it StaticEvent.instance.mainRotScript

Thanks marcel!

by user 103054507105067008

No problem :slightly_smiling_face: youre welcome

I’ve made the package imported be one for the static events like your example scene, then I want to do things with local code in the main project I am working on so I have made a class in the main project called StaticEvents for that which I am serializing as a public variable on the package-side MyJsInteropSampleComponent but it’s not working. What am i doing wrong? It would be super useful if the samples showed how to use the static instances with gameobjects in the scene somehow

import { serializable } from "@needle-tools/engine";
import { Behaviour, showBalloonMessage } from "@needle-tools/engine";
import { StaticEvents } from "C:/Unity_Projects/EatonInteractive/Needle/MainScene/src/scripts/StaticEvents";
export class MyJsInteropSampleComponent extends Behaviour {
  @serializable(StaticEvents)
  //@ts-ignore
  staticLocal: StaticEvents;

  static get instance() {
    return this._instance;
  }
  private static _instance: MyJsInteropSampleComponent;

  constructor() {
    super();
    MyJsInteropSampleComponent._instance = this;
  }
}

// this method is exported inside the package.json main file
export function openHotspot(hotsptId: number) {
  console.log(
    "static events: ",
    MyJsInteropSampleComponent.instance.staticLocal
  );
  //MyJsInteropSampleComponent.instance.mainRotScript.openHotspot(hotsptId);
}

// this method is exported inside the package.json main file
export function myJsInteropMethod() {
  console.log(
    "static events: ",
    MyJsInteropSampleComponent.instance.staticLocal
  );
  //showBalloonMessage(
  //MyJsInteropSampleComponent.instance.mainRotScript.name.toString()
  //);
}

by user 103054507105067008

Your import path is wrong. You can not import from a absolute system filepath. Where does the script MyJsInteropSampleComponent live?

I get Cannot read properties of undefined (reading 'staticLocal') at openHotspot

by user 103054507105067008

In an npm package the same as the sample, the import is absolute because I’m trying to import something from the main project into a package that is outside it

by user 103054507105067008

Why? I dont understand the structure to be honest

I guess it might not need to be inside a package to work, will try to do it in the project. Will post back only if I’m really stuck

by user 103054507105067008

I’m just trying to make a script in my project that is a static instance that can be called from external javascript that has some references to gameobjects in the scene

by user 103054507105067008

External js means: it’s inside a script.js or a script tag or something else inside your main project?