Forum Discussion

Pastew's avatar
Pastew
Partner
8 months ago
Solved

How to access Methods and Properties of a referenced Entity in TypeScript (Desktop Editor)

Hi,
I have two local scripts

  1. SomeLocalItem.ts
  2. AnotherLocalItem.ts

SomeLocalItem has reference to Entity with AnotherLocalItem.

I want:

1) Inside SomeLocalItem invoke method on referenced AnotherLocalItem.
2) Inside SomeLocalItem read some property from AnotherLocalItem.

Note, both scripts are local, so Behaviour.ts doesn't work here without rewriting it to work locally. Is there simpler way?


SomeLocalItem.ts

import * as hz from 'horizon/core';
import { AnotherLocalItem } from 'AnotherLocalItem';
class SomeLocalItem extends hz.Component<typeof SomeLocalItem> {
  static propsDefinition = {
    anotherLocalItemEntity: { type: hz.PropTypes.Entity }
  };

  start() {
    this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnButton1Down, () => {this.onButton1Down();});
  }

  onButton1Down() {
    this.anotherLocalItem = this.props.anotherLocalItemEntity as AnotherLocalItem; // This doesn't work, how to assign the entity to the component?
    this.anotherLocalItem.printToConsole('Hello from SomeLocalItem'); // I want to invoke this method, how?
    console.log('Level of anotherLocalItem: ', this.anotherLocalItem.level); // Or print it's public property, how?
  }
}

hz.Component.register(SomeLocalItem);

 

 AnotherLocalItem.ts

import * as hz from 'horizon/core';
export class AnotherLocalItem extends hz.Component<typeof AnotherLocalItem> {

  static propsDefinition = {
    level: { type: hz.PropTypes.Number, default: 1}
  };

  public level: number = 1;
  preStart(): void {
    this.level = this.props.level;
  } 

  start() {
  }

  public printToConsole(message: string) {
    console.log('AnotherLocalItem.printToConsole: ', message);
  }
}
hz.Component.register(AnotherLocalItem);
  • Thanks!

    Now I understand, it works if the player already owns both entities. Example below

    import * as hz from 'horizon/core';
    import { AnotherLocalItem } from 'AnotherLocalItem';
    
    // This script is set as Local
    class SomeLocalItem extends hz.Component<typeof SomeLocalItem> {
      static propsDefinition = {
        anotherLocalItemEntity: { type: hz.PropTypes.Entity }
      };
    
      start() {
        this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnGrabStart, (isRightHand: boolean, player: hz.Player) => {
          this.entity.owner.set(player);
          this.props.anotherLocalItemEntity!.owner.set(player);
    
          // This will not work!
          // const anotherLocalItem = this.props.anotherLocalItemEntity!.getComponents(AnotherLocalItem)[0];
          // anotherLocalItem.printToConsole('Hello from SomeLocalItem');
        });
    
        this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnButton1Down, () => this.onButton1Down());
      }
    
      onButton1Down() {
        const anotherLocalItem = this.props.anotherLocalItemEntity!.getComponents(AnotherLocalItem)[0];
        anotherLocalItem.printToConsole('Hello from SomeLocalItem');
        console.log('SomeLocalItem.onButton1Down: Level read from anotherLocalItem: ', anotherLocalItem.level);
      }
    }
    hz.Component.register(SomeLocalItem);

3 Replies

  • Have you tried getComponent()? Not sure if it works on local scripts but worth a try. I wrote this from memory, untested.

    import * as hz from 'horizon/core';
    import { AnotherLocalItem } from 'AnotherLocalItem';
    class SomeLocalItem extends hz.Component<typeof SomeLocalItem> {
      static propsDefinition = {
        anotherLocalItemEntity: { type: hz.PropTypes.Entity }
      };

      start() {
        this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnButton1Down, () => {this.onButton1Down();});
      }

      onButton1Down() {
       this.props.anotherLocalItem.getComponent(AnotherLocalItem)[0].printToConsole('Hello World')
      }
    }

    hz.Component.register(SomeLocalItem);

     

  • Try this

    ```
    let components =  this.props.anotherLocalItemEntity.as(Entity).getComponents(AnotherLocalItem);
    if (components.length) {
    components[0].printToConsole(...);
    }

    ```
  • Thanks!

    Now I understand, it works if the player already owns both entities. Example below

    import * as hz from 'horizon/core';
    import { AnotherLocalItem } from 'AnotherLocalItem';
    
    // This script is set as Local
    class SomeLocalItem extends hz.Component<typeof SomeLocalItem> {
      static propsDefinition = {
        anotherLocalItemEntity: { type: hz.PropTypes.Entity }
      };
    
      start() {
        this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnGrabStart, (isRightHand: boolean, player: hz.Player) => {
          this.entity.owner.set(player);
          this.props.anotherLocalItemEntity!.owner.set(player);
    
          // This will not work!
          // const anotherLocalItem = this.props.anotherLocalItemEntity!.getComponents(AnotherLocalItem)[0];
          // anotherLocalItem.printToConsole('Hello from SomeLocalItem');
        });
    
        this.connectCodeBlockEvent(this.entity, hz.CodeBlockEvents.OnButton1Down, () => this.onButton1Down());
      }
    
      onButton1Down() {
        const anotherLocalItem = this.props.anotherLocalItemEntity!.getComponents(AnotherLocalItem)[0];
        anotherLocalItem.printToConsole('Hello from SomeLocalItem');
        console.log('SomeLocalItem.onButton1Down: Level read from anotherLocalItem: ', anotherLocalItem.level);
      }
    }
    hz.Component.register(SomeLocalItem);