How do I play a .glb animation?

Hi there.

I tried a few different guides on how to make my GLB with animations play in three.js. I tried this for starts, but it doesn’t seem to work: three.js docs, nor do I know the name of my animation. I tried to console.log() it, but I couldn’t find the function to do that either.

I am sure the animation is applied correctly as I opened the .GLB in blender and tested the animation.

This is my site where the three.js script is active: https://www.mattiasbaldi.com/
Code + .glb
three.js (3.7 KB)
mb.glb (659.2 KB)

The script does not contain the animation mixer. I removed that as it interfered with loading my model. So my question is just how I play the .glb. I’m aware there is no animation mixer or anything else in the code.

Here is a demo made for a fun challenge (mixamo character control + skin < 100 lines of code)
https://github.com/Oxynt/three-mixamo/tree/main

The demo doesn’t use pre-set animation name, and instead yoink it directly from the object arrays itself.
As well as subclip 'ing the frames to create/cut new animations on the fly from the main timeline.
It’s dirty, but it’s compact. So you may quickly find what you need to complete your code.

You use an AnimationMixer to play animations. It’s what it does.

let action = mixer.clipAction( gltf.animations[0] , yourModel);
action.play()

mixer.update( 1/60 )

So why does that not work for me? I applied it here;

`//loader
      const loader = new GLTFLoader();
      let model;
      loader.load('/mb.glb', (gltf) => {
    model = gltf.scene;
        scene.add(model);
       //scaling
       model.scale.set(.14,.14,.14); // Adjust scale for the model
    
        let action = mixer.clipAction( gltf.animations[0] , model);
action.play()

mixer.update( 1/60 )

      });`

Oh the mixer.update(1/60) needs to be in your animation loop!
Right before your renderer.render() is a good spot…
The mixer combines all the animations running on the object, and applies their weighted sum to the skinned meshes.

Did that, no change :confused:

Your .glb looks usable if you drag it on here…

I don’t know what’s wrong with your code…

Here’s a minimal example: Glitch :・゚✧
I do the loading/playback in test.js

edit: whoops i guess glitch screwed up and reverted… i’ll have to remake it.

Your GLB is also functional in my GLTF Viewer and you can see the whole viewer’s code in my repository.

Maybe try introducing the clock, similar to this (which is what my viewer is using):

	var clock, mixer;

	clock = new THREE.Clock();

	// use the following once the loader has loaded the model
	if (gltf.animations.length > 0) {
		mixer = new THREE.AnimationMixer( gltf.scene );
		gltf.animations.forEach( clip => { mixer.clipAction( clip ).loop = THREE.LoopRepeat; } );
		mixer.clipAction( gltf.animations[ 0 ] ).play();
	}

	// add to the rendering loop
	if ( mixer ) mixer.update( clock.getDelta() );

Hi there! Appreciate your response. Unfortunately, that doesn’t seem to work either. Can you confirm that I added it correctly? I added the code like so:

//clock
	var clock, mixer;

	clock = new THREE.Clock();

//loader
      const loader = new GLTFLoader();
      let model;
      
      
loader.load('/mb.glb', (gltf) => {
    model = gltf.scene;
        scene.add(model);
       //scaling
       model.scale.set(.14,.14,.14); // Adjust scale for the model

       	// use the following once the loader has loaded the model
       		if (gltf.animations.length > 0) {
		mixer = new THREE.AnimationMixer( gltf.scene );
		animations.forEach( clip => { mixer.clipAction( clip ).loop = THREE.LoopRepeat; } );
		mixer.clipAction( gltf.animations[ 0 ] ).play();
	}

      });

And then added the mixer to the render loop at the end of my code.

	// add to the rendering loop
	if ( mixer ) mixer.update( clock.getDelta() );

I’m still relatively new to programming. Your code looks a little overwhelming, and I can’t seem to find where “animations” are present, although I did notice you are using an .fbx though. Could that be the difference - I suppose .glb animations should be supported in three though.

1 Like

Hey sorry, that glitch I made… I got your GLB loading and animating in it, then glitch crapped out and reverted it… I’m gonna redo it and paste here…


  this.init = async () => {
    let mixer = new THREE.AnimationMixer();
    let clock = new THREE.Clock();
    let glb = await gltfLoader.loadAsync(
      "https://cdn.glitch.global/b94889ff-9799-42c0-abe7-53076d5ef713/mb%20(1).glb?v=1706930112304"
    );
    let clip = mixer.clipAction(glb.animations[0], glb.scene);
    clip.play();
    scene.add(glb.scene);

    this.update = () => {
      mixer.update(clock.getDelta());
    };
  };

Code: Glitch :・゚✧

Live site: https://neon-garnet-lobe.glitch.me

In the glitch… all the THREEJS boilerplate setup is in script.js

Test.js is the stuff specific to loading and playing your glb/animation.

I used an async function so I could use the loadAsync method on the loader instead of using the callback… it makes the flow a little easier to understand.
this.update is called by script.js from the apps rendering loop.

1 Like

Maybe try using the code that @manthrax posted.

Also rely on the browser to show you the errors, since it suggests that you currently don’t have the code if ( mixer ) in front of the mixer.update( clock.getDelta() );.

Here is the picture of the errors from your website:

1 Like

@mattias_98 just in case if you are to try my code again, I have just edited and corrected my code which should fix the animations error showing in the picture I posted previously.

It was supposed to be gltf.animations.forEach( clip => ... instead of animations.forEach( clip => ...

1 Like

Update

Merci beaucoup

1 Like