Rigidbody.teleport in setTimeout

when i put the rigidbody.teleport function in the setTimeout function, it doesn’t work. see code.

var Shoot = pc.createScript('shoot');

Shoot.attributes.add('guPoint', {type: 'entity'});
Shoot.attributes.add('bullet', { type: 'entity' });

// initialize code called once per entity
Shoot.prototype.initialize = function() {
    
};

// update code called every frame
Shoot.prototype.update = function(dt) {
    // Press X to shoot 
    if(this.app.mouse.wasPressed(pc.MOUSEBUTTON_LEFT)) {
        this.shoot();
    }
};

Shoot.prototype.shoot = function(){
 var gp = this.guPoint.getPosition();  
    this.bullet.rigidbody.applyImpulse(0,5,0);
    
setTimeout(function(){ 
this.bullet.setPosition(gp);
},1000);
};



// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/

it works without setTimeout. But i need it for one second then teleport back to the gun point. pls help and fix this glitch.

It seems you are directly setting the position of a dynamic rigidbody, which won’t work. Instead, replace this.bullet.setPosition(gp); with this.bullet.rigidbody.teleport(gp);

1 Like

i tried that, it said rigidbody is not defined

Does it have an rigidbody? if so then try this

var t = this
setTimeout(function(){ 
  t.bullet.setPosition(gp);
},1000);

i used all of that, i doesn’t work.

The issue here is that var gp = this.guPoint.getPosition(); returns you a reference to the pc.Vec3 rather than a copy. This means that gp is always representing the current position of the guPoint. What you have intended to have is a copy:

Shoot.prototype.shoot = function(){
    // Get a copy of the position as a new pc.Vec3 object
    var gp = this.guPoint.getPosition().clone();  
    this.bullet.rigidbody.applyImpulse(0,5,0);
    
    // the .bind ensures that we take the instance of this script as the
    // context of 'this' in the function
    setTimeout(function(){ 
        this.bullet.setPosition(gp);
    }.bind(this),1000);
};

However, what I think you really want to do here is disable the bullet after a second as passed otherwise the bullet will just be floating in midair:

Shoot.prototype.shoot = function(){
    var gp = this.guPoint.getPosition();  
    this.bullet.rigidbody.teleport(gp);
    this.bullet.enabled = true;
    this.bullet.rigidbody.applyImpulse(0,5,0);
    
    // the .bind ensures that we take the instance of this script as the
    // context of 'this' in the function
    setTimeout(function(){ 
        this.bullet.enabled = false;
    }.bind(this),1000);
};

I think what he is trying to do is to have the bullet respawn back to it’s original spot before it was shot after a certain amount of time has passed after being shot.

this doesn’t work for some strange reason

var Shoot = pc.createScript('shoot');

Shoot.attributes.add('guPoint', {type: 'entity'});
Shoot.attributes.add('bullet', { type: 'entity' });

// initialize code called once per entity
Shoot.prototype.initialize = function() {
   
};

// update code called every frame
Shoot.prototype.update = function(dt) {
    // Press X to shoot 
    if(this.app.mouse.wasPressed(pc.MOUSEBUTTON_LEFT)) {
        this.shoot();
    }
};

Shoot.prototype.shoot = function(){
 var gp = this.guPoint.getPosition();  
    this.bullet.translateLocal(0,0,-6);
var goBack = this.bullet.rigidbody.teleport(gp);

    setTimeout(function(){ 

var goBack = this.bullet.rigidbody.teleport(gp);
},1000);
};


// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/

Hello @jus.co_ding_me_23,

Try and using it as an anonymous function, like this:

setTimeout(() => { 
    var goBack = this.bullet.rigidbody.teleport(gp);
},1000);

But this will only work if you’re using ES6 syntax. Another way is to add .bind(this) like this:

setTimeout(function(){ 
    var goBack = this.bullet.rigidbody.teleport(gp);
}.bind(this),1000);