cancel
Showing results for 
Search instead for 
Did you mean: 

Can't teleport player to a location when pressing a UI button in meta horizon worlds desktop editor

kyle174
Member

I've been trying to find different ways for the past week to teleport my player to a spawn point gizmo whenever it presses a button on my custom UI screen. 

I have 2 scripts called GameManage2 and MainMenuUI. The MainMenuUI is supposed to send a broadcast event to my GameManage2 which is then supposed to send my player to the spawnPointGizmo I had set up. I made sure that the script settings is set up so that it's specifically that spawnPointGizmo and it gives this error: "[Respawn] parameter 0 expected a PlayerID but got a None". Code snippets for both the MainMenuUI and GameManage2 script are below...

b9167665-892b-42c7-b123-53c859852c0f.png

3d4632d0-c387-4c75-8ddd-b06317d1997a.png

===================Main Menu UI=================================

initializeUI() {
    let myLogo: any = this.props.Logo
    let myLogoSource: ui.ImageSource = ui.ImageSource.fromTextureAsset(myLogo)
    this.bndLogoSource.set(myLogoSource)

    return ui.View({
      children: [
        ui.Text({
          text: 'Savor Sim',
          style: {
            top: -300,
            fontSize: 100,
            color: 'black',
            fontWeight: 'bold',
            textAlign: 'center',
            borderRadius: 20,
          }
        }),
        MyPrompt({
          /*
            Below, the onClickYes object that is passed to the MyPrompt() function is actually
            a simple arrow (inline) function, which calls out to the public function doYes().
            That function writes a simple message to the console.

            These two references are passed to the MyPrompt function, which references the
            onClickYes property (a function) for the Yes button and the onClickNo property (a function)
            for the No button.
          */
          onClickYes: () => {
            doYes();
            this.sendLocalBroadcastEvent(teleportPlayer, {player: hz.Player});
          },
          onClickNo: () => {
            doNo();
          },
        }),
 
=================================================================
 
===================Game Manage 2=============================
 
class GameManage2 extends hz.Component<typeof GameManage2> {
  static propsDefinition = {
    spawnLocation: { type: hz.PropTypes.Entity },
    // player: { type: hz.Player },
  };

  private player1 =  hz.Player;

  start() {

    /** Fires any time a user joins the world */
    this.connectCodeBlockEvent(
      this.entity,
      hz.CodeBlockEvents.OnPlayerEnterWorld,
      (player1: hz.Player) => {
        console.log('Player entered world:', player1);
        return player1;
      }
    );
   
    this.connectLocalBroadcastEvent(teleportPlayer,
      (data: { player: hz.Player }) => {
        this.doTeleport(data.player);
      }
    );
  }

  doTeleport(player: hz.Player): void {
    const playerId = player.id;
    // console.log(`Teleporting player with ID: ${playerId}`);

    if (!player) {
      console.error('Player is undefined. Cannot teleport.');
      return;
    }

    (this.props.spawnLocation as any).as(hz.SpawnPointGizmo).teleportPlayer(player);
    console.log('teleported player');
  }
 
}
hz.Component.register(GameManage2);
1 REPLY 1

GizimoGames
Member

Hello Kyle, I hope you are doing well,
I have only looked over your code a little bit but it appears you problem may lie with this line here:

this.sendLocalBroadcastEvent(teleportPlayer, {player: hz.Player});
I have had to make the assumption the teleportPlayer value you have here is a LocalEvent class that is perhaps stored in a const elsewhere, for my answer i'll be assuming the teleportPlayer value looks like this:
const teleportPlayer = new LocalEvent<Player>();
Now back to the previous line that I was talking about, I am assuming the issue likely lies in the part that I have marked as bold:
this.sendLocalBroadcastEvent(teleportPlayer, {player: hz.Player});
I would instead recommend that you insert a reference to the player that is currently interacting with the UI.
Alternatively, if you do not wish to pass in a reference to the player and instead want to receive an event without any parameters you could use the player1 variable on your GameManage2 script. This would however, require a small change to your OnPlayerEnterWorld functionality as follows:
 this.connectCodeBlockEvent(
      this.entity,
      hz.CodeBlockEvents.OnPlayerEnterWorld,
      (player: hz.Player) => {
        console.log('Player entered world:', player1);
        this.player1 = player;
      }
    );

You would then plug in your player1 variable like so:
(this.props.spawnLocation as any).as(hz.SpawnPointGizmo).teleportPlayer(player1);
I would also recommend not using as any as this can commonly lead to some code silently failing, to avoid using this in the above code you cana check if your prop value is undefined before using and return out of the function while throwing an error if it is undefined.

I do hope that this message helps you in your endeavours, best of luck with your work and if you are still experiencing a problem with this after this message feel free to reply and I'll be happy to try helping again.
Kind regards,
GizimoGames