mcpField
R
r3f-animation

r3f-animation

github.com/enzed開発1312.1k 回インストール8 週間前に更新
リポジトリ

r3f-animation について

r3f-animationは、React Three Fiberプロジェクトのアニメーション実装と確認を支援するエージェントスキルです。適切な制御方法の選択、時間と性能の管理、フレームレートやデマンドレンダリングでの検証を案内します。

主な機能

  1. 01タスクに応じた制御方法の選択
  2. 02refsとuseFrameによる連続動作
  3. 03既存GLTFクリップの再生
  4. 04時間とフレームレートの管理
  5. 05デマンドレンダリングと後処理の検証

活用シーン

  1. 01メッシュ変換やシェーダーのアニメーション
  2. 02個別のGLTFアクションの再生
  3. 03デマンドレンダリング時の動作確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/enzed/r3f-skills --skill r3f-animation

インストール後、Claude Code で/r3f-animationを入力して読み込まれたか確認します。

同梱ファイルreferences/clips.md

詳細

React Three Fiber のアニメーション

まず、インストールされている Fiber、Drei、React のバージョンを確認してください。以下の例は Fiber 9 / React 19 を対象としています。既存のアニメーションライブラリで要件を満たせる場合は、そのまま使用してください。

アニメーションの担当を選ぶ

  • 連続的な変形や uniform には useFrame と refs を使用します。React の状態では、選択中、開いている、アクティブといった離散的な目標を表します。
  • 作成済みの GLTF クリップには Drei の useAnimations を使用します。独立してアニメーションするインスタンスとクリーンアップについては、クリップの再生を参照してください。
  • 連携したトランジションにはプロジェクトのスプリング/トゥイーンライブラリを使用します。追加する前に React の peer dependencies を確認してください。メッシュをアニメーションさせるためだけに状態管理ライブラリを導入しないでください。
  • シミュレーション対象のボディ変形は Rapier に任せます。シミュレーションとメッシュの位置で競合させず、物理 API を通じてキネマティックターゲットをアニメーションさせてください。

アイドル状態に戻れる減衰

Canvas の内側にマウントします。これは frameloop="demand" でも動作します。ボックスをクリックすると、目標が変わります。

import { useEffect, useRef, useState } from 'react'
import { useFrame, useThree } from '@react-three/fiber'
import { MathUtils, type Mesh } from 'three'

export default function Example() {
  const mesh = useRef<Mesh>(null)
  const [active, setActive] = useState(false)
  const invalidate = useThree((state) => state.invalidate)
  const target = active ? 1 : -1
  useEffect(() => { invalidate() }, [target, invalidate])

  useFrame((_, delta) => {
    if (!mesh.current) return
    // Cap a visual transition's resume jump, not a physics simulation step.
    const x = MathUtils.damp(mesh.current.position.x, target, 6, Math.min(delta, 0.1))
    const moving = Math.abs(x - target) > 0.001
    mesh.current.position.x = moving ? x : target
    if (moving) invalidate()
  })

  return (
    <mesh ref={mesh} name="moving-box" onClick={() => setActive((value) => !value)}>
      <boxGeometry />
      <meshStandardMaterial color={active ? 'orange' : 'coral'} />
    </mesh>
  )
}

タイミングとパフォーマンス

  • delta は秒単位です。速度を position += velocity * delta のように積分します。指数平滑化には MathUtils.damp または 1 - exp(-lambda * delta) を使った lerp を使用してください。固定の lerp 比率はリフレッシュレートによって変わります。また、delta * speed は目標値を超えることがあります。
  • ベクトルやクォータニオンは再利用し、毎フレームの割り当ては避けてください。向きの補間には、ラップ境界をまたいで Euler 角を個別に lerp するのではなく、クォータニオン補間を使用してください。
  • タイムライン/クロックの管理元は一つにしてください。Fiber 9 では引き続き state.clock が提供されます。Three.js で新しい単独の Clock インスタンスが非推奨になったため、Fiber の内部実装を置き換えないでください。独立した Three.js のタイミング処理には、インストールされているリリースの Timer を参照してください。
  • demand モードでは、外部アニメーションシステムは動作中に無効化を要求する必要があります。同期待ちのアニメーションを開始する前に無効化し、最初のフレームで動きが飛ばないよう、次のフレームで開始するようにしてください。
  • 対応している場合は、フレームコールバック内で高速に変化する外部状態を直接読み取ってください(例:ストアの getState())。React は UI に関係する変更だけを購読します。外部サブスクリプションはクリーンアップしてください。
  • 通常の React 再レンダーでアニメーションが停止すると説明しないでください。コンポーネントをメモ化する前に、実際の処理量とサブスクリプション頻度をプロファイリングしてください。
  • オブジェクトを非表示にしても、フレームコールバックやミキサーは停止しません。適切な場合は、高負荷のアニメーションを明示的に一時停止してください。装飾的な動きでは、動きを抑える設定を尊重してください。
  • 繰り返しの振動やシェーダーの動きでは、経過時間から位相を求められます。再現性が必要なシミュレーションには、任意の delta のクランプではなく、固定ステップ方式が必要です。

検証

異なるフレームレートでの動き、バックグラウンドから復帰したときの挙動、目標を繰り返し変更したときの挙動を比較してください。demand モードでは、オブジェクトが再び動き出し、目標に到達して、フレームの要求を停止することを確認してください。クリップについては、2 つのインスタンスで異なるアクションが再生されることをテストしてください。

参考資料

コメント