Web上でBlenderでつけたアニメーションの複数切り替え

この記事はTech KAYAC Advent Calendar 2019の14日目の記事です。

こんにちは!クライアント事業部技術部の@yumikokhです。
新卒4年目、今年からWebフロント→サーバーサイド所属になりましてお仕事で演出ごりごりすることはなくなったのですが、
趣味でWebGLや3Dソフト(Cinema4D, Blender)の勉強をしています。

今回は、Blenderでつけた複数のキーフレームアニメーションをWeb上で切り替える方法を最短ルートでお届けします!

つくるもの

サンプルページを用意しました

シンプルですね!
こんなかんじで、アニメーションを切り替える画面を作ります。

準備

  • Blender v2.8-

    • こちらからインストールできます
    • Blenderは超高機能な上に無料でオープンソースな3Dソフトです。
    • 今回はjsライブラリの Three.js を使用するため、 glTF2.0形式のデータが必要です
    • glTFはJSONによって3Dモデルやシーンを表現する便利なフォーマットのことです(ざっくり)
    • v2.7xまでglTF2.0のエクスポートにはアドオンが別途必要でしたが、v2.8から標準装備になったそう(^^)
  • なんらかのエディター

    • 特にこだわりがなければVSCodeで間違いないでしょう
    • サンプルコードをそのまま使えばファイル名変えるだけでOK

Blenderでアニメーションの元データをつくろう

さっそく新しいファイルを開きましょう!おきまりの箱が見えていますね

f:id:wyumikokh:20191213074709p:plain
最初の画面
この箱に適当にアニメーションをつけていきます。

キーフレームを打つ

キューブを選択した状態で K を打つと、↓のメニューがでてきます。
まずは位置にキーフレームを打ちたいので位置を選択します。

f:id:wyumikokh:20191213075007p:plain
キーフレーム挿入メニュー

最初のフレームにキーが打たれました!
↓がタイムラインで、青い縦線が今いる位置なので、1フレーム目が表示されています。(タイムラインの領域が狭い場合は境界をホバーすると領域をドラッグできそうなカーソルに変わるはずです)

f:id:wyumikokh:20191213075227p:plain
最初のフレーム

次に、適当に青線をドラッグしてフレーム位置を変えてみましょう。
適当で大丈夫ですがだいたい10フレームくらいに動かしたら、Z位置の値を変えて箱を浮かせてみましょう
値を変えたあとは右側のひし形をクリックしてキーを打ちます。キーを打たないと値はリセットされるのでご注意を!

f:id:wyumikokh:20191213080339p:plain
Z位置を変えてキーをうつ

同じ要領で適当に20フレームあたりに青線をドラッグし、Z位置を0にしてキーを打ちましょう。
これで1つ目のキーフレームアニメーションは完成です!
青線を最初の位置に戻して再生ボタンorスペースキーを打つと箱が飛び跳ねる(とまで躍動感はないですがw)はずです!

f:id:wyumikokh:20191213080834p:plain
キーフレーム完成

アクションを作成

次に左上のアイコンを選択し、ドープシートに切り替えます。

f:id:wyumikokh:20191213081224p:plain
ドープシートに切り替える

切り替えたらドープシート と書かれたプルダウンメニューから アクション を選択します。
すると↓のような表示が現れます。ここでWeb上で切り替えるためにアクション単位で保存します。
CubeAnimation をお好きな名前でOKです。
今のアニメーションをアクションとして保存するには、名前右の盾のようなアイコンをクリックします。

f:id:wyumikokh:20191213081523p:plain
アクション

これで1つ目のアニメーションを設定できました!

2つ目以降のアニメーション

先程の盾アイコンの右にあるアイコンをクリックして新規アクションを作成+今あるキーを削除し、先程の要領で新しいアニメーションを作成します。

ファイル書き出し

ファイル > エクスポート > glTF2.0 を選択し、「モディファイアーを適用」「+Yが上」にチェックして書き出します。

f:id:wyumikokh:20191213082337p:plain
glTF2.0をエクスポート

Web上で動かそう

実装する前に、glTF Viewer で先程書き出したデータが正しく表示されるか確認します。
glTF Viewerからもアニメーションの切り替えができるはずです

↑で問題がなければ実装です!
実装と言っても、Three.jsに必要な機能がほとんど準備されてます!やったぜ!

全体のコードはこちらにあるので、カメラやライティングなどベースとなるオブジェクトについては割愛させていただきます。

glTFデータの読み込み

GLTFLoaderを使います。指定したglTFデータを読み込み、Threejs用にいい感じにparseしてくれます。

const loader = new THREE.GLTFLoader();
loader.load("./sample-anim.glb", gltf => {
  // ロード後の処理
  scene.add(gltf.scene); // gltfのシーンを乗っける
  // gltf.animationsの中にBlenderで作成したアニメーションデータが入っている
}

アニメーションの切り替え

AnimationMixerを通して、先程読み込んだanimationを AnimationAction に変換します

// animationはgltf.animationsの中の要素
const mixer = new THREE.AnimationMixer(gltf.scene);
const action = mixer.clipAction(animation);

AnimationActionはアニメーションのタイムラインの制御を簡単にしてくれるもので、↓のようにチェーンで直感的な記述ができます。
loopの有無、種類の指定やアニメーションが切り替わるときに唐突に切り替わるのを防ぐためFadein/outする関数も用意されてます。

action.reset().play().fadeIn(0.5);

さいごに

いかがだったでしょうか? Blenderは学生時代に少〜しだけかじってたのですがUIがかなり美しくなってて驚きでした。これで無料ってほんとありがたいですね。
3D表現が気軽にできて、夢広がります(^o^) 最後までご覧いただきありがとうございました!!誰かのお役に立てたら幸いです!