#three.js #gltf #react-three-fiber
#three.js #gltf #реакция-трехслойная
Вопрос:
Я загружаю модель GLTF, загруженную из Sketchfab, в приложение React. Модель загружается отлично, но анимация не воспроизводится вообще. Я пробовал разные подходы. Есть идеи?
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:
Решение
- Мне пришлось использовать узел вместо сцены и выбрать «rootNode» (консоль.зарегистрируйте узел и выберите то, что показалось мне основным узлом, модель содержала дюжину узлов)
- Обновление микшера по фреймам с помощью useFrame
- Применить анимацию к модели (немного обновлено)
Рабочий код:
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>
)
}
Теперь это работает
Комментарии:
1. проверьте это twitter.com/0xca0a/status/1336056832025047041
Ответ №2:
Вам нужно вызвать mixer.update(delta) в useFrame внутри вашего компонента:
import { useFrame } from 'react-three-fiber'
function Model({url}) {
.
.
.
useFrame((scene, delta) => {
mixer?.update(delta)
})
.
.
.
Ответ №3:
- Поместите ваш glb-файл в общедоступный файл.
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>
);
};