Play GLTF Animations by Name in Three.js

This article explains how to target, extract, and play a specific animation from a loaded GLTF file in Three.js. You will learn how to initialize the AnimationMixer, locate an animation clip by its string name within the GLTF asset’s animation array, and continuously update the mixer within your render loop to bring your 3D model to life.

To play a specific animation from a GLTF file, you need to use Three.js’s animation system, which relies on three main components: AnimationMixer, AnimationClip, and AnimationAction.

Step 1: Initialize the AnimationMixer

The AnimationMixer is the player for animations on a specific 3D object. When your GLTF model loads, instantiate a mixer using the loaded scene.

let mixer;

const loader = new GLTFLoader();
loader.load('model.gltf', (gltf) => {
    const model = gltf.scene;
    scene.add(model);

    // Create the mixer and associate it with the model
    mixer = new THREE.AnimationMixer(model);
});

Step 2: Extract the Animation Clip by Name

The loaded gltf object contains an animations array holding multiple AnimationClip objects. You can find a specific animation by its name using the built-in utility method THREE.AnimationClip.findByName().

// Inside your loader callback:
const animationName = 'Walk'; // The name of the animation in your GLTF file
const clip = THREE.AnimationClip.findByName(gltf.animations, animationName);

Step 3: Create the AnimationAction and Play

Once you have the desired AnimationClip, convert it into an AnimationAction using the mixer, then call .play().

if (clip) {
    const action = mixer.clipAction(clip);
    action.play();
} else {
    console.warn(`Animation named "${animationName}" was not found.`);
}

Step 4: Update the Mixer in the Animation Loop

Animations require constant updates over time. You must update your AnimationMixer inside your application’s render/requestAnimationFrame loop using a THREE.Clock to calculate the time difference (delta) between frames.

const clock = new THREE.Clock();

function animate() {
    requestAnimationFrame(animate);

    const delta = clock.getDelta();

    // Update the mixer to progress the active animations
    if (mixer) {
        mixer.update(delta);
    }

    renderer.render(scene, camera);
}

animate();