Access to fields outside oflifecycle methods

Why do we not have access to the fields extended by the Behavior class outside of lifecycle methods?
Example:

export class Clickable extends Behaviour {

  @serializable(EventList)
  myEvent?: EventList;

  onEnable(): void {
    console.log('name', this.name); // defined
  }

  hotSpotPress(id: number) {
    console.log('name', this.name); // undefined
  }
}

Original Post on Discord

by user 219335701790064640

Hello there – we have an experimental AI bot :robot: that might be able to help you with your question. Would you like to try this out?

You do have. How are you accessing it?

If you take a look at the example, the name variable returns undefined in the hotSpotPress method

by user 219335701790064640

I’m asking how you call hotSpotPress - you can access each field everywhere, this is just JavaScript/TypeScript.

E.g. if in your onEnable method you call this.hotSpotPress(5) it will also log the name.

I can show you the code. It is a simple raycast script, ask if anything is unclear

export class Clickable extends Behaviour {
  @serializable()
  myStringField: string = 'Hello World';

  start() {}

  onEnable(): void {
    this.myEvent?.addEventListener(this.hotSpotPress);
    console.log('onenable', this.name);
  }

  onDisable(): void {
    this.myEvent?.removeEventListener(this.hotSpotPress);
  }

  @serializable(EventList)
  myEvent?: EventList;

  update(): void {
    if (this.context.input.getPointerDown(0)) {
      const intersections = this.context.physics.raycast();

      for (let I = 0; I < intersections.length; I++) {
        const element = intersections[I];

        if (element.object === this.gameObject) {
          this.myEvent?.invoke();
        }
      }
    }
  }

  hotSpotPress() {
    console.log('hotspotpress', this.name); // this does not work
  }
}

by user 219335701790064640

Ah, I see. You’re not binding the method – this is specific to JavaScript (independent of Needle Engine). Effectively you’re calling hotSpotPress not on the right instance in the way you’ve written it above.
We have some “why” and “how to do it right” here: Typescript Essentials | Needle Engine Documentation

either with automatic binding through using arrow functions

hotSpotPress = () => {
    console.log('hotspotpress', this.name); // this does work
}

or with explicit binding using bind

let func; 
...
func = this.hotSpotPress.bind(this);
this.myEvent?.addEventListener(func);
...
this.myEvent?.removeEventListener(func);

I agree it’s a weird syntax, especially coming from C# events, but it’s how JavaScript is designed
(this.hotSpotPress is just the method itself, not the method on that particular object instance)

Right! Yes that is weird coming from C#

Thanks!

by user 219335701790064640