@react-three/fiberでBlenderアニメーション付きglbファイルを表示する

@react-three/fiberでBlenderアニメーション付きglbファイルを表示する

2023/12/11
ReactThree.jsBlender

前提

  • glbはこちらの記事を参考にしてgltfjsxでコンポーネントに変換しています。

Blenderでアニメーションをつける

Blenderでアニメーションをつけてglbファイルを出力します。
アニメーションは以下のような簡単なものを作成して、glb形式で書き出します。

アニメーションに名前を設定します。この名前がReact側で利用するときに指定する名称になります。

React側で表示する

gltfjsxでコンポーネント化します。
書き出されたファイルを外部から利用できるようにdefaultをつけてexportします。

Model.tsx

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.15 public/models/animation.glb -o src/components/AnimationModel.tsx -r public 
*/

import React, { useRef } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";

// defaultをつける
export default function Model(props) {
  const group = useRef();
  const { nodes, materials, animations } = useGLTF("/models/animation.glb");
  const { actions } = useAnimations(animations, group);

  return (
    <group ref={group} {...props} dispose={null}>
      <group name="Scene">
        <mesh
          name="MyCube"
          geometry={nodes.MyCube.geometry}
          material={materials.Material}
        />
      </group>
    </group>
  );
}

useGLTF.preload("/models/animation.glb");

App.tsx

import "./App.css";
import { Canvas } from "@react-three/fiber";
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { Environment, OrbitControls } from "@react-three/drei";
import Model from "./components/Model";

const canvas = css`
  height: 100vh !important;
  width: 100vw !important;
`;

function App() {
  return (
    <>
      <Canvas css={canvas} camera={{ position: [0, 3, 10], fov: 30 }} shadows>
        <OrbitControls />
        <Environment preset="sunset" background blur={0.5} />
        <ambientLight intensity={1} />
        <directionalLight position={[0, 5, 5]} intensity={1} castShadow />
        <Model scale={0.7} position={[0, 0.57, 0]} rotation={[0, -3.1, 0]} />
      </Canvas>
    </>
  );
}

export default App;

表示はこんな感じになります。

アニメーションを再生する

ModelコンポーネントにuseAnimationsで取得するactionsをconsole.logで出力してみると、Blenderで指定したアニメーションが取得できていることがわかります。

これを利用してアニメーションを再生します。
useEffectでアニメーションを再生します。

  useEffect(() => {
    actions["MyCubeAction"]!.play();
  }, [actions]);

これでアニメーションが再生されます。

関連記事

なにかお手伝いできることがあればご連絡ください。

お問い合わせはこちらから

※Googleフォームが表示されます