0
votes

I load GLTF model downloaded from Sketchfab in React app. Model loads perfectly well, but animation doesn`t play at all. I tried different approaches. Any ideas?

function Model({ url }) {

  const model = useRef()
  const { scene, animations } = useLoader(GLTFLoader, url)
  const [mixer] = useState(() => new THREE.AnimationMixer())
  useEffect(() => void mixer.clipAction(animations[0], group.current).play(), [])


  return(
        <primitive
          ref={model}
          object={scene}
        />
  )
}
2

2 Answers

0
votes

Solution

  1. I had to use node instead of scene and select "RootNode" (console.log node and choose what seemed to me the main node, the model contained a dozen of nodes)
  2. Update mixer by frames with useFrame
  3. Apply animation to the model (a bit updated)

Working code:


function Model({ url }) {

   const group = useRef()
  const { nodes, scene, materials, animations } = useLoader(GLTFLoader, url)
 const actions = useRef()
  const [mixer] = useState(() => new THREE.AnimationMixer())
  useFrame((state, delta) => mixer.update(delta))
  useEffect(() => {
    actions.current = { idle: mixer.clipAction(animations[0], group.current) }
    actions.current.idle.play()
    return () => animations.forEach((clip) => mixer.uncacheClip(clip))
  }, [])


  return(
     <group ref={group} dispose={null}>
        <primitive
          ref={group}
          name="Object_0"
          object={nodes["RootNode"]}
        />
        </group>
  )
}

Now it works

0
votes

You need to call mixer.update(delta) in useFrame inside your component:

    import { useFrame } from 'react-three-fiber'
    function Model({url}) {
    .
    . 
    .
        useFrame((scene, delta) => {
            mixer?.update(delta)
        })
    .
    . 
    .