How to append animations from gltf-loader to scene?

When I am exporting my selected models from Blender I got two Objects from the GLTF.loader. One is the gltf.scene Object and one is the gltf.animations Object.

In Blender each animation is assigned to a specific or more Objects, but this relation is gone after the GLTF export. The animations in the gltf.animations object don’t have a key or something else to point to the assigned scene object.

I noticed that each object in the gltf.scene array has a property array called animations, but it is always empty.

I need a way to bind an animation directly to the animations array shown above.

Do I have to change something inside blender to automatically append the animation data to the scenes animation array in export?

Or is the solution to append the Animations from the gltf.animations object by myself?

It might depend on the animation.
For example path-follow and others need bake keyframes
you could try to bake keyframes

I forgot …
of course you need a mixer

mixer = new THREE.AnimationMixer( yourscene );
gltf.animations.forEach( ( clip ) => {
      mixer.clipAction( clip ).play();
} );

and to update it in animation

as you can see here
https://threejs.org/examples/#webgl_animation_keyframes

First — thank you for your quick reply.
This is the approach I had before. But this example from the documentation triggers the animation right after the model is loaded.

At the moment I am trying to fire an event via the THREE.Raycaster and then I am resolving the animation on my own by attaching a custom property with the userData in Blender (line 10).
But this seems to be very hacky and not very flexible.

Here is the Example Code I am using right now:

// The Intersects array returns all objects wich are hit by the Raycaster
// aka Hover Target
const intersects = this.raycaster.intersectObjects( this.scene.children, true);
    for ( let i = 0; i < intersects.length; i ++ ) {
        // If the Raycasted element has the desired type continue
        if(intersects[i].object.userData.type == 'CityMarker') {
            // When the custom Property (Blender) named »animation« is the same  
            // as the Action (Blender Animation), play the animation once
            this.actions.forEach((action) => {
                if (action._clip.name == intersects[i].object.userData.animation) {
                    action.setLoop( THREE.LoopOnce );
                    action.play()
                } 
            })
        }
    }
}

I mean basically it works, but I think this is not really a smooth implementation bc it wouldnt scale well. E.g. if I want to add more than one animation later on.

So I thought it would be a better way to have the animations array in the gltf.scene filled up with the corresponding animations, so I can access them directly by the object.

I tried to bake the animation keyframes but still, the animations array in the gltf.scene stays empty.

1 Like

it is better to separate the problems
At least one action in blender you should have it, but the array looks empty.
Obviously you have checked the animations in the export panel.
Try to load your file in a standard code, like the example, or on an online viewer … to figure out if it’s a file or code problem

Interestingly an old blender trick worked to resolve the problem. I was on Blender Version 2.92 and downgraded to 2.82 and now the exporter binds the animations to the gltf.scene animation array.

In the next days I will investigate where the problem might come from but anyone having the same problem, this is a workaround for now.

Note: Correct me if I am completely wrong with my assumption and the behaviour is somehow intended and not a bug?

GLTFLoader makes no attempt to assign the scene.animations property. Instead, it returns a top-level animations list with its results. It’s very unusual to see glTF models with more than one scene, so you can mostly just use that list as needed.

If you’re not sure all of the animations are being exported from Blender at all I would suggest opening the model in a viewer like gltf-viewer.donmccurdy.com/ and checking that everything is there. If not, you may need to check the Blender docs (note the requirement of stashing or making NLA Tracks of inactive Actions).