Best practice to teleport an object

Hi.
I am trying to create a teleport script.
Had two seperate tries and both failed:

try 1:

import { Behaviour, serializable } from "@needle-tools/engine"
import { Object3D } from "three";

export class TeleportPoint extends Behaviour {
    /** The object to move on teleport */
    @serializable(Object3D) objectToTeleport?: Object3D;

    public teleport(){
        // teleport
        this.objectToTeleport?.translateX(this.gameObject.position.x);
        this.objectToTeleport?.translateY(this.gameObject.position.y);
        this.objectToTeleport?.translateZ(this.gameObject.position.z);
        
        // rotate
        // TODO: rotate to this.gameObject.forward
    }
    
}

try2 :

import { Behaviour, serializable } from "@needle-tools/engine"
import { Object3D } from "three";

export class TeleportPoint extends Behaviour {
    /** The object to move on teleport */
    @serializable(Object3D) objectToTeleport?: Object3D;

    public teleport(){
        // teleport
        this.objectToTeleport!.position.x = this.gameObject.position.x;
        this.objectToTeleport!.position.y = this.gameObject.position.y;
        this.objectToTeleport!.position.z = this.gameObject.position.z;
        
        // rotate
        // TODO: rotate to this.gameObject.forward
    }
    
}

I would like to know the best practice on teleporting please

Original Post on Discord

by user 198447544408342528

If its not a physics object you can use this.objectToTeleport.position.copy(this.gameObject.position) - altough keep in mind position in threejs is local position. In Unity it’s world position. So what you can use tho is our helper methods (e.g. getWorldPosition and setWorldPosition)

If it was a physics object (has a rigidbody) you should use the method teleport() on the rigidbody component to not get super extreme forces

I’d recommend you read this guide as well and maybe the typescript essentions guide: Scripting Introduction | Needle Engine Documentation
There are some differences between C# and JS to be aware of

Nothing too extreme but important to know - and you’ll learn it fast :slightly_smiling_face:

regarding “they both failed” - what does happen when you call the method? How do you call it? They both should also be working (well except the fact that position is local space so that might just be it here)

I assumed it might be the local position shtick. It behaved like it.
On the first try, I was teleported backwards, so I guess it was because the TP point is on z=-6 on local.

Does .teleport() on rigidbody rotate? If not, are there any best practices there?

by user 198447544408342528

teleport() worked perfect, thanks :slightly_smiling_face:
(if one does not want to use RB, getWorldPos and setWorldPos works fine :ok_hand:)

by user 198447544408342528

teleport() does NOT rotate you. Am trying for an easy way to rotate correctly using world rotation

by user 198447544408342528

Right, teleport only has position arguments right now. Good point. But you can just call resetVelocities on the rigidbody as well and then use the setWorldPosition and setWorldRotation methods

or setWorldQuaternion

setWorldRotation did not work for me

import { Behaviour, Rigidbody, getWorldPosition, serializable } from "@needle-tools/engine"

export class TeleportPoint extends Behaviour {
    /** The object to move on teleport */
    @serializable(Rigidbody) objectToTeleport?: Rigidbody;

    public teleport(){
        // teleport
        this.objectToTeleport?.teleport(getWorldPosition(this.gameObject));

        // rotate
        let rotation = this.gameObject.rotation;
        this.objectToTeleport?.setWorldRotation(rotation.x, rotation.y, rotation.z);
    }
    
}

I gave resetVelocities a try as well:

import { Behaviour, Rigidbody, getWorldPosition, serializable } from "@needle-tools/engine"

export class TeleportPoint extends Behaviour {
    /** The object to move on teleport */
    @serializable(Rigidbody) objectToTeleport?: Rigidbody;

    public teleport(){
        // teleport
        this.objectToTeleport?.teleport(getWorldPosition(this.gameObject));

        // rotate
        this.objectToTeleport?.resetVelocities();
        let rotation = this.gameObject.rotation;
        this.objectToTeleport?.setWorldRotation(rotation.x, rotation.y, rotation.z);
    }
    
}

by user 198447544408342528

You might want to pass in the world rotation as well :wink:

const rotation = getWorldRotation(this.gameObject) or shorthand this.worldRotation

Marcel you’re one heck of man! And so patient for my newbie problems :rofl:

by user 198447544408342528

any idea why I still dont get rotated?

import { Behaviour, Rigidbody, getWorldPosition, getWorldRotation, serializable } from "@needle-tools/engine"

export class TeleportPoint extends Behaviour {
    /** The object to move on teleport */
    @serializable(Rigidbody) objectToTeleport?: Rigidbody;

    public teleport(){
        // teleport
        this.objectToTeleport?.teleport(getWorldPosition(this.gameObject));

        // rotate
        let rotation = getWorldRotation(this.gameObject);
        this.objectToTeleport?.setWorldRotation(rotation.x, rotation.y, rotation.z);
    }
    
}```

*by user 198447544408342528*

I figured it might be beacuse I am trying to rotate a RigidBody, but when I do this.objectToTeleport?.gameObject.setWorldRotation I get an error that GameObject type doesnt have setWorldRotation function

by user 198447544408342528

The threejs class doesnt, yes. You can use our utility method (import { setWorldRotation } from "@needle-tools/engine" or use the util method on components (this.setWorldRotation not this.gameObject.setWorldRotation) - that being said I think we can patch it (add the method) to the threejs objects as well (we already add some other things there anyways

this is what I meant:

import { Behaviour, Rigidbody, getWorldPosition, getWorldRotation, serializable, setWorldRotation } from "@needle-tools/engine"
import { Object3D } from "three";

export class TeleportPoint extends Behaviour {

    /** The object to move on teleport */
    @serializable(Rigidbody) objectToTeleport?: Rigidbody;

    public teleport(){
        // teleport
        this.objectToTeleport?.teleport(getWorldPosition(this.gameObject));

        // rotate
        let rotation = getWorldRotation(this.gameObject);
        this.objectToTeleport?.gameObject.setWorldRotation(rotation.x, rotation.y, rotation.z); // ERROR : Property 'setWorldRotation' does not exist on type 'GameObject'.ts(2339)
    }
    
}```

*by user 198447544408342528*

I did import setWorldRotation and still no use

by user 198447544408342528

I am trying to rotate objectToTeleport

by user 198447544408342528

Change this.objectToTeleport?.gameObject.setWorldRotation(rotation.x, rotation.y, rotation.z); to setWorldRotation(this.objectToTeleport, rotation);