It sounds like the issue is that the physics bodies are still carrying their previous velocity and forces when you swap the positions. So even if phy.change() moves them, the physics solver continues with the existing momentum and they immediately influence each other again.
If the goal is to only teleport the balls and not transfer any physical state, you usually need to reset their velocities when you change the position. Otherwise the engine keeps the previous motion data.
Something like this idea normally works better:
let r = [
{
name: left.name,
pos: ball.position,
drivePosition: true,
reset: true,
linearVelocity: [0,0,0],
angularVelocity: [0,0,0]
},
{
name: ball.name,
pos: left.position,
drivePosition: true,
reset: true,
linearVelocity: [0,0,0],
angularVelocity: [0,0,0]
}
];
phy.change(r, true);
Resetting the velocities prevents the physics engine from applying the previous motion state after the position swap.
Another thing to check is that you are passing a cloned position instead of the same vector reference. If both bodies receive the same Vector3 reference it can cause weird updates. Sometimes doing ball.position.clone() and left.position.clone() fixes that.
So the main things are
1 reset velocities when teleporting
2 use cloned positions
3 keep reset:true so the physics state is rebuilt
That usually stops the objects from inheriting each other’s movement state.