import React, { useEffect, useRef } from 'react'; import { Canvas, useFrame, useLoader } from '@react-three/fiber'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { VRMLoaderPlugin, VRMUtils } from '@pixiv/three-vrm'; import { createVRMAnimationClip, VRMAnimationLoaderPlugin } from '@pixiv/three-vrm-animation'; import { AnimationMixer, GridHelper, AxesHelper } from 'three'; import { OrbitControls } from '@react-three/drei'; const VRM_URL = '/ai.vrm'; const VRMA_URL = '/idle.vrma'; function Avatar() { const mixerRef = useRef(null); const vrmRef = useRef(null); const gltf = useLoader(GLTFLoader, VRM_URL, (loader) => { loader.register((parser) => new VRMLoaderPlugin(parser)); }); const vrma = useLoader(GLTFLoader, VRMA_URL, (loader) => { loader.register((parser) => new VRMAnimationLoaderPlugin(parser)); }); useEffect(() => { const vrm = gltf.userData.vrm; vrmRef.current = vrm; VRMUtils.removeUnnecessaryJoints(vrm.scene); vrm.humanoid.resetPose(); vrm.scene.rotation.y = Math.PI; if (vrma.userData.vrmAnimations && vrma.userData.vrmAnimations.length > 0) { const clip = createVRMAnimationClip(vrma.userData.vrmAnimations[0], vrm); mixerRef.current = new AnimationMixer(vrm.scene); mixerRef.current.clipAction(clip).play(); } }, [gltf, vrma]); useFrame((state, delta) => { if (mixerRef.current) mixerRef.current.update(delta); if (vrmRef.current) vrmRef.current.update(delta); }); return ; } export default function App() { return (
); }