three.jsでglTFのアニメーションを再生する記事はあったのですが複数のアニメーションを切り替える方法は書かれていなかったのでなかったので書いてみました
複数のアニメーションがあるglTFの3Dモデルが前提に書かれています。
まずglTFを読み込んでシーンに配置してアニメーションを再生します。
シーンの作成等は省略します
const loader = new THREE.GLTFLoader();
const model = 'hoge.gltf';
//glTFの読み込み
loader.load(model, (data) => {
const gltf = data;
const object = gltf.scene;
//アニメーションの読み込み
const animations = gltf.animations;
mixer = new THREE.AnimationMixer(object);
const anime = mixer.clipAction(animations[0]);
anime.play();
//シーンに追加
scene.add(object);
});
この
mixer.clipAction(animations[0]);
の[]
の数字を書き換えれば別のアニメーションが再生されます。
glTFのanimations
の上から0から順に指定できるみたいです。
このままじゃ条件分岐で別のアニメーションを指定しても一度再生したアニメーションはループ再生しっぱなしになって他のアニメーションと混ざるので関数に切り離します。
const loader = new THREE.GLTFLoader();
const model = 'hoge.gltf';
//glTFの読み込み
loader.load(model, (data) => {
const gltf = data;
const object = gltf.scene;
const animations = gltf.animations;
mixer = new THREE.AnimationMixer(object);
//シーンに追加
scene.add(object);
//アニメーションの切り替え
function chengeanime(num) {
mixer.stopAllAction();
const anime = mixer.clipAction(animations[num]);
anime.setLoop(THREE.LoopOnce)
anime.clampWhenFinished = true
anime.play();
}
});
stopAllAction()
を使ってすべてのアニメーションを一旦ストップしsetLoop(THREE.LoopOnce)
でループを無効、clampWhenFinished
をtrue
にすればアニメーションの最後のフレームでアニメーションが終了します。
これで条件分岐でアニメーションが切り替えられるようになったと思います。
setLoop(THREE.LoopOnce)
を書かなければループしつつアニメーションが混ざりません。
VScodeの拡張機能でglTFをプレビューするとアニメーションの名前も一緒に表示されていたのでおそらく名前で指定する方法もあると思いますが調べてもわからなかったので断念。