react-three-fiber如何提取和播放动画

Posted

技术标签:

【中文标题】react-three-fiber如何提取和播放动画【英文标题】:How to extract and play animation in react-three-fiber 【发布时间】:2021-01-04 05:49:30 【问题描述】:

我有 .gltf 动画模型。我成功加载了模型,但无法播放嵌入的动画。我想知道是否可以通过任何方式解决它。顺便说一句,我正在对此做出反应。提前谢谢你。

在这里你可以找到模型 https://drive.google.com/file/d/1ZVyklaQuqKbSliu33hFxdyNpg4EQtcBH/view?usp=sharing

这是我尝试过的代码。

import * as THREE from 'three'
import  OrbitControls  from "three/examples/jsm/controls/OrbitControls"
import React,  Suspense,useRef, useEffect, useState  from 'react'
import  Canvas ,extend, useThree, useFrame from 'react-three-fiber'
import  GLTFLoader  from 'three/examples/jsm/loaders/GLTFLoader'
import './style.module.css'

extend( OrbitControls )

function Hardware() 
  const [scene, set] = useState()
  useEffect(() => 
  new GLTFLoader().load("tern_construct_animation.gltf", gltf => 
    set(gltf.scene)
    const mixer = new THREE.AnimationMixer(gltf.scene)
    gltf.animations.forEach(clip => mixer.clipAction(clip).play())
  )
, [])

return scene ? <primitive object=scene /> : null



const Controls = () => 
  const orbitRef = useRef()
  const  camera, gl  = useThree()

  useFrame(() => 
    orbitRef.current.update()
  )

  return (
    <orbitControls
      autoRotate
      maxPolarAngle=Math.PI / 3
      minPolarAngle=Math.PI / 3
      args=[camera, gl.domElement]
      ref=orbitRef
    />
  )

const animated_element = () => 
  return (
    <Canvas camera= position: [0, 0, 5] >
      <ambientLight intensity=2 />
      <pointLight position=[40, 40, 40] />
      <Controls/>
      <Suspense fallback=null>
        <Hardware/>
      </Suspense>
    </Canvas>
  )


export default animated_element;

【问题讨论】:

如果你做console.log(gltf.animations),你会看到什么?里面有东西吗? 是的,我确实得到了一个包含许多 AnimationClip 项目的数组。看看这里我已经发布了image of the console@Marquizzo 【参考方案1】:

我也遇到了同样的问题。

这是对我有用的代码。

显然这个组件在树中被Suspense 包裹得更高。

import  useLoader, useFrame  from 'react-three-fiber';
import  
    GLTFLoader 
 from 'three/examples/jsm/loaders/GLTFLoader';
import * as THREE from 'three'

const Model = props => 
    const model = useLoader(
        GLTFLoader,
        props.path
    )

    // Here's the animation part
    // ************************* 
    let mixer
    if (model.animations.length) 
        mixer = new THREE.AnimationMixer(model.scene);
        model.animations.forEach(clip => 
            const action = mixer.clipAction(clip)
            action.play();
        );
    

    useFrame((state, delta) => 
        mixer?.update(delta)
    )
    // *************************

    model.scene.traverse(child => 
        if (child.isMesh) 
            child.castShadow = true
            child.receiveShadow = true
            child.material.side = THREE.FrontSide
        
    )

    return (
        <primitive 
            object=model.scene
            scale=props.scale
        />
    )


export default Model;

【讨论】:

谢谢,useFrame((state, delta) =&gt; mixer?.update(delta) ) 为我工作。我以前尝试使用useFrame(( clock ) =&gt; mixer?.update(clock.getDelta()));

以上是关于react-three-fiber如何提取和播放动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在threejs或react-three-fiber中加载相同的gltf模型

threejs + vanilla js 和 react-three-fiber + create-react-app 的颜色差异

bufferGeometry setFromPoints 与 react-three-fiber

React-Three-Fiber (R3F):GLTF 加载程序加载问题。为啥我看不到我的模型?

通过 react-three-fiber 中的道具传递纹理的 URL

如何使用 youtube-dl 从播放列表中的 Youtube 视频中提取上传日期、标题、URL 和持续时间?