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