Search code examples
javascriptanimationthree.jsgltf

How can I loop a GLTF animation in three.js with random intervals?


I am experimenting with creating games using Three.js and I would like to ask if there is a way to animate a GLFT model but instead of having the animation loop I would like to use random intervals. In my case, the game is about taking care of frogs (but I'm cool so I spelled it phrogs) and as an idle animation I want the frogs to croak randomly. Further on in development I also want to add randomly playing animations for movement, eating etc but right now I only need the croaking animation. Here is the code that loads the model and animates it:

const basePhrog = new GLTFLoader()
var obj
basePhrog.load('assets/models/Phrogs/base phrog/phrog.gltf', function (gltf) {
  mixer = new THREE.AnimationMixer(gltf.scene)
  obj = gltf.scene
  var action = mixer.clipAction(gltf.animations[0])
  scene.add(gltf.scene)
  action.play()
})

My animate loop looks like this:

function animate () {
  requestAnimationFrame(animate)
  var delta = clock.getDelta()
  if (mixer) mixer.update(delta)
  renderer.render(scene, camera)
}
animate()

I hope you can help and thank you for any suggestions!


Solution

  • The glTF file provides an animation (or THREE.AnimationClip in three.js terminology), and the playback of that clip is managed by a THREE.AnimationAction instance. The code in your example will begin playing that animation immediately, and loop it forever, but the AnimationAction does not have to be used that way.

    Instead, you could wait and play the action at random intervals:

    var action = mixer.clipAction( animation );
    action.loop = THREE.LoopOnce;
    
    // Play animation randomly every 1-10s.
    setInterval(() => {
      action
        .reset()
        .play();
    }, Math.random() * 9000 + 1000);
    

    You can continue to update the AnimationMixer as you are doing now, regardless of whether the animation is playing at any given time.

    If you're later trying to play multiple animations on the same object, some of the APIs for transitioning between two animations may be helpful, see the animation / skinning / morph example.