Handling animations (useAnimations)

Back to Modules

Handling Animations with useAnimations in React Three Fiber

When working with 3D models that include animations (like those often found in glTF/GLB files), React Three Fiber, in conjunction with @react-three/drei, provides the useAnimations hook to simplify their playback and control.

What is useAnimations?

The useAnimations hook from @react-three/drei is designed to streamline the process of managing and playing animation clips associated with a 3D model. It abstracts away much of the boilerplate code typically required for Three.js animation mixers and actions.

How to Use useAnimations

The typical workflow involves:

  1. Load your 3D model: You'll usually load a glTF/GLB model using useGLTF (also from @react-three/drei). This hook provides the animations array from your model.
  2. Pass animations to useAnimations: You pass the animations array and a ref to the mesh or group that contains the animated model to useAnimations.
  3. Control animation actions: The hook returns an object with actions (an object mapping animation clip names to THREE.AnimationAction instances) and mixer (the THREE.AnimationMixer instance). You can then use methods like actions[clipName].play(), actions[clipName].stop(), actions[clipName].setWeight(), etc., to control the animations.

Example: Playing a Model Animation

This example demonstrates how to load a glTF model with animations and play a specific animation clip using useAnimations. Note that this requires a React environment to run and a .glb model with embedded animations.

import React, { useEffect, useRef, Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { useGLTF, useAnimations, OrbitControls } from '@react-three/drei';

function AnimatedModel(props) {
  const group = useRef();
  // Load the glTF model and its animations
  const { scene, animations } = useGLTF(props.url);
  // Get animation actions and mixer
  const { actions } = useAnimations(animations, group);

  useEffect(() => {
    // Play a specific animation when the component mounts
    // Replace 'YourAnimationName' with the actual name of an animation clip in your model
    // You can inspect your glTF model in a viewer to find animation clip names.
    const animationName = 'Idle'; // Common animation name, replace if needed
    if (actions[animationName]) {
      actions[animationName].play();
    }

    // Optional: Clean up animation when component unmounts
    return () => {
      if (actions[animationName]) {
        actions[animationName].stop();
      }
    };
  }, [actions]); // Re-run effect if actions change

  return (
    <group ref={group} {...props} dispose={null}>
      <primitive object={scene} />
    </group>
  );
}

export default function App() {
  return (
    <Canvas camera={{ position: [0, 1, 3] }}>
      <ambientLight intensity={0.5} />
      <pointLight position={[10, 10, 10]} />
      <Suspense fallback={null}>
        <AnimatedModel url="/path/to/your_animated_model.glb" /> <!-- Replace with your model path -->
      </Suspense>
      <OrbitControls />
    </Canvas>
  );
}

Key Points: