Three.js 不在 React 中播放动画

Three.js doesn't play animation in React

我在 React 应用程序中加载了从 Sketchfab 下载的 GLTF 模型。模型加载完美,但动画根本无法播放。我尝试了不同的方法。有什么想法吗?

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}
        />
  )
}

解决方案

  1. 我不得不使用节点而不是场景和 select "RootNode" (console.log 节点并选择在我看来是主节点,模型包含十几个节点)
  2. 使用 useFrame
  3. 按帧更新混音器
  4. 为模型应用动画(有点更新)

工作代码:


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>
  )
}

现在可以了

您需要在组件内的 useFrame 中调用 mixer.update(delta):

    import { useFrame } from 'react-three-fiber'
    function Model({url}) {
    .
    . 
    .
        useFrame((scene, delta) => {
            mixer?.update(delta)
        })
    .
    . 
    .
  • 将您的 glb 文件放入 public 文件管理器。
import { Suspense, useEffect, useRef } from "react";
import { useAnimations, useGLTF } from "@react-three/drei";

export const Character = (props: any) => {
  const ref = useRef() as any;

  const glf = useGLTF("assets/Soldier.glb");
  const { actions } = useAnimations(glf.animations, ref);

  useEffect(() => {
    actions.Run?.play();
  });

  return (
    <Suspense fallback={null}>
      <primitive 
        ref={ref} 
        object={glf.scene}
      />
    </Suspense>
  );
};