Issue with Resetting Mesh Position When Using new Vector3 in Array

Hi everyone,

I’m working on a Babylon.js scene with physics-enabled meshes. I want to reset the position of a mesh when I press the R key.

I noticed something strange:

  • When I store new BABYLON.Vector3 objects directly in an array, pressing R only works the first time.

  • But when I assign the vector to a variable first and then use that variable in the array, it works correctly every time.

Here’s a playground link demonstrating the issue: https://playground.babylonjs.com/#FSMQBW#55

Why does this happen, and how can I make the reset work reliably even when using new Vector3 in an array?

Thanks in advance!

because you’re modifying that same arr[1] vector after you assign it to mesh.position, because the array and the mesh both hold onto the same object reference.

you can clone the Vector before assigning to avoid this.

1 Like

Thanks for the explanation! I tried using .clone() as you suggested. It works fine in the Playground, but in my actual code it still doesn’t fully reset the meshes.

let playerPosL = [
    new Vector3(15, 0, 0),
    new Vector3(3, 0, 1.5),
    new Vector3(3, 0, -1.5),
    new Vector3(9, 0, -4),
    new Vector3(9, 0, 4),
   ]

function resetAllPos() {

    playerLeft.forEach((pl, i) => {
       if (pl && pl?.physicsBody) {
           pl.physicsBody.setAngularVelocity(Vector3.Zero());
           pl.physicsBody.setLinearVelocity(Vector3.Zero());
           pl.physicsBody.setMotionType(PhysicsMotionType.STATIC);
           pl.physicsBody.disablePreStep = false;
           pl.position = playerPosL[i].clone()
}
}

)}
1 Like

I don’t see anything wrong w/ just that, can you repro that in a PG?

Ah, I see! The issue was that earlier in my code I was setting the position like this:

p.position = playerPosL[(i % playerPosR.length)]

Changing it to use .clone() fixed the problem:

p.position = playerPosL[(i % playerPosR.length)].clone()

So the mesh wasn’t fully resetting because it was still referencing the same Vector3 object.

1 Like

But another problem: I added this for performance in resetAllPos function :

function resetAllPos() {

    playerLeft.forEach((pl, i) => {
       if (pl && pl?.physicsBody) {
           pl.physicsBody.setAngularVelocity(Vector3.Zero());
           pl.physicsBody.setLinearVelocity(Vector3.Zero());
           pl.physicsBody.setMotionType(PhysicsMotionType.STATIC);
           pl.physicsBody.disablePreStep = false;
           pl.position = playerPosL[i].clone()
           scene.onAfterRenderObservable.addOnce(() => {
            if (pl && pl?.physicsBody)
              pl.physicsBody.disablePreStep = true;
          })
     }
})

However, the reset function doesn’t work after this.

1 Like

I replaced onAfterPhysicsObservable with onAfterRenderObservable, and it worked.

2 Likes