Home > Back-end >  Three.js animation mixer doesn't update unless logged in animation loop
Three.js animation mixer doesn't update unless logged in animation loop

Time:12-12

Very strange behaviour in JavaScript, a simple AnimationMixer.update(delta) doesn't work unless I console.log it:

// This works
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  // Update mixers...
  Object.values(sandbox.models).forEach(x => (x.mixer && console.log(x.mixer.update(clock.getDelta()))));
}

// These don't work
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  // Update mixers...
  Object.values(sandbox.models).forEach(x => (x.mixer && (x.mixer.update(clock.getDelta()))));
}

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  // Update mixers...
  Object.values(sandbox.models).forEach(x => (x.mixer && void(x.mixer.update(clock.getDelta()))));
}

Then, when playing the animation by AnimationMixer.clipAction(animation).play() does not play unless I do the first one.

This is very strange, why does the mixer only update when logged the return value?

I can't show all the code because it's too long and won't work because I have linked files too.

And as you may know you can't log thousands of times per second, it's stupid in general and will slow down the game.

CodePudding user response:

You should never call Clock.getDelta() more than once in your animation loop. Otherwise the delta values will be near 0 (since you get the elapsed time between the last getDelta() call). So try it like so:

function animate() {
  requestAnimationFrame(animate);
  const delta = clock.getDelta();
  renderer.render(scene, camera);
  // Update mixers...
  Object.values(sandbox.models).forEach( x => {
    if (x.mixer) x.mixer.update(delta);
  } );
}

Also avoid the usage of Object.values() per frame since it will return a new array on each invocation which is bad for performance (this just leads to GC overhead).

  • Related