Spineでできること〜エディタのTipsとAPI使用例〜
「QualiArts Advent Calendar 2019」23日目担当の小倉です!
普段はプロジェクトを横断して、2DアニメーターとしてSpineでSDや動くイラストの制作、Live2Dのディレクション、After Effectsで動画制作などを行っています。
Spineの特徴
Spine(普通名詞のspineと区別してSpine2Dとも)とはゲーム用2Dアニメーションソフトウェアで、SDや動くイラストなど、2Dイラストを表現豊かに動かすコンテンツのあるゲームで広く使われています。
「ガールフレンド(仮)」聖櫻エリアのアニメーション)
2Dイラストをアニメーションさせるツールとして、よくSpineとLive2Dはともに話題に上がります。
ここ数年の動向としては、SpineはIKなどのコンストレイント機能によって多様なアニメーションに対応できる汎用性の高さと、制作フットワーク・処理負荷の軽さ、Unityとの親和性を生かした、ゲームでキャラクターに限らずいろんなものを豊かに組み込みで動かすための用途が多く、Live2Dはハイクオリティな顔の向き変更や物理演算によるリアル頭身キャラクターに特化した豊かな表現の作りやすさと、パラメータによる効率的な可動域の制御、イラストPSDとの親和性を生かした、2Dアバターや映像作品などへの用途が多いように感じます。
Spineは3Dの技術・操作方法などを取り入れているように感じる点が多く、Live2Dはモデリングの過程がまさに2Dイラストの絵作りという感じで、それぞれ操作感は異なりますが、双方とも見た目は近いものを仕上げることが可能なので、どちらを使っているかは確かめるまで分からないものもちょくちょくあります。
今回の記事は、上記を踏まえてSpineを検討していてできることを知りたい方や、既にSpineを軽く使っていてもっと知りたいという方へ向けて、細かな操作方法は省いたものとなりますので、とりあえずキャラを動かしてみたい!という方は、去年にリアル頭身のカードイラストを動かす記事を書いているのでそちらや、他の方の記事をまず見ることをおすすめします。
SpineでGF(仮)のガールを動かしてみた(メイキング1/2:Spine基礎編)
SpineでGF(仮)のガールを動かしてみた(メイキング2/2:カードイラスト実践編)
今回は、現在最新のver 3.8を用いて(※1)、以前の記事では紹介しなかった機能やちょっとした小技、Spineランタイムとの連携の一例などをご紹介します。Spineランタイムとの連携のところでは、JavaScriptですがサンプルコードも載せています。(※2)
Spineの動く仕組み
Spineは、画像(領域アタッチメント)をスロットというものに入れて管理しています。
部位ごとに分けたパーツのスロットをボーンに入れて回転・移動・拡縮などをさせて、その変化をキーフレームとして記録することで動かしています。ボーンを入れ子にして階層構造を作ることができるので、効率的に複雑なアニメーションを作ることができます。
単純に回転させたロゴを、Y軸を縮小して押し潰したボーンの中へ入れることで、楕円状に回るアニメーションを作ることができます。
領域アタッチメントを細かく区切るようにメッシュに変換し、その頂点ごとにボーンの影響度のウェイトを設定することで、段階的に曲げることもできるので、これによって柔らかさを表現したり、パーツ同士を繋いだりすることができます。
布の上部制御用ボーンと下部制御用のボーンを用意しウェイトを割り当て、地面へ布がついて反る感じや揺れを表現
素材の準備
部位ごとに分けたイラストデータを用意し、Spineに付属しているスクリプトを使って、Spineで読み込むことのできる配置データJSONとバラバラのPNGを作ります。
スクリプトは、
- Photoshop
- Illustrator
- After Effects
- GIMP
- Inkscape
用が公式で用意されていて、Affinity Designerはソフトウェア側が書き出しに対応しているそうです。
Photoshop用スクリプトについて
静止画を読み込む場合はPhotoshop用のスクリプトが一番高機能で、レイヤーグループ名などによって事前に少し整理ができるので、こちらを使うのがおすすめです。公式のスクリプト用Githubでも使い方が読めるので、ここでは特によく使うものをピックアップしてご紹介します。
レイヤーグループ名を「[bone] name」にする
あらかじめ「name」という名前のボーンの中に、そのレイヤーグループ内の画像を入れた状態にしてくれます。デフォルトだとrootボーン直下に全ての画像が並ぶので、動くイラストのような一つのファイルで複数の要素があるときに、まとめておくためによく使います。
レイヤーグループ名を「[slot] name」にする
ボーンのときと同様に「name」というスロットにまとめることができます。スロット内には複数の領域アタッチメントを含めることができますが、表示できるのは1つだけなので、切り替え系のパーツに使用します。
レイヤーグループ名を「[merge] name」にする
結合してワンパーツとして扱って書き出してくれるので、今後加筆修正する可能性があり、まだ素材を結合したくないときに使用します。ただ、このスクリプトはレイヤー数が多すぎると実行速度が数分レベルで遅くなることがあります。このオプションを使うとレイヤー数が多くなりがちなので要注意です。
Spineエディタでの制作
Spineのメニューから「データのインポート」を選び、配置データJSONを読み込ませると、パーツが元のイラストデータと同じように配置され、1つのスケルトンとなります。
Spineはボーンやコンストレイントなどを組んでいくSETUP(※3)モードと、キーフレームを打って動きをつけていくANIMATE(※4)モードがあり、この2つのモードを行き来しながら制作を進めていきます。
制作スタンスにもよりますが、SDなど1つのスケルトンでたくさんのモーションを付けるものは、セットアップをまず集中して、細かいところまでウェイト付けやリギング(キャラクターなどを直感的に動かすための仕組みを作ること)を済ませ、モーションを付けたあとは微調整程度に抑えることで、モーションが付けやすく手戻りの少ない制作ができ、動くイラストなど複雑だがモーションの数が少ないものは、ざっくりボーンやコンストレイントなどを設定した状態で一旦必要なモーションを軽く付け、途切れているところや柔らかく曲げたいところなどをピンポイントでウェイトを調整し、動き方自体が不自然なところはSETUPモードに戻ってボーンの位置を調整するというフローで作ると、過剰なセットアップを省きながらモーション付けも同時進行できるため、スピーディーな制作をすることができます。
SETUPモードでのTips·3.8の新機能の紹介
ボーン
作成
「作成」ツールの状態でドラッグすることで、現在選択中のボーンの子として新しいボーンを作成できますが、「ctrl」(Macの場合「command」)を押しながら画像をクリック(クリックできないときは「Options」の「Images」のカーソル行にチェックを入れ、ビューポート上で画像をクリック選択できるようにする)してからドラッグすることで、その画像のスロットを新しいボーンの中に入れ、ボーンの名前もそのスロットの名前と同じものが設定された状態にできるので、素早くセットアップを進めることができます。
以前の記事で作った明音で、ポニテをボーンの中に入れながら作る様子
分割
選択したボーンを右下の「分割」ボタンから複数のボーンに分割することができます。
オプションの「フィボナッチ」は末端に行くにつれ、だんだんとボーンの長さが短くなるように分割することができ、髪などの揺れものに使うと自然な多段揺れを作ることができます。
公式のSpine Tipsに動画があり、このページは他にも有用な情報が多いので、定期的に見ることをおすすめします!
メッシュ
Spineは、領域アタッチメントをメッシュに変換した直後は長方形の状態で、その後手動でメッシュの分割の仕方などを調整することができます。
メッシュ
3.8では、画像の輪郭に沿ったメッシュを自動で生成できるようになりました…!!
外周のみで、内部の分割の仕方は手動で調整する必要がありますが、欠けることなくかなりの精度です!
テクスチャ・パッキング
Spineは、ゲームなどに組み込む際は最後に画像を並べてまとめたテクスチャを書き出し、こちらを使用します。3.8ではメッシュの形状に合わせて自動で詰めてくれるオプション(ポリゴン)が追加されました。今後は上述のメッシュトレーシングと併用することで、かなりサイズを節約できます!
左:長方形 右:ポリゴン
コンストレイント機能
Spineにはボーンを「制約」することで、複数のボーンを同時に制御しやすくする3つのコンストレイント機能があります。そのうちの1つの、トランスフォーム(回転や位置、拡縮、シアー)を連動させる「トランスフォームコンストレイント」については以前の記事で詳しく紹介しましたので、今回の記事では残りの2つについてご紹介します。
IKコンストレイント
このコンストレイントを設定すると常にターゲットのボーンの方向へボーンを回転させて向かせることができます。親子ボーンを2本までは連携させて適用できるので、膝など関節のあるパーツを直感的に制御するために使用されることが多いです。
また、オプションで「圧縮」は元のボーンの長さより短くするのを許可するか、「ストレッチ」は長くするのを許可するか、「統一」はボーンのXY拡縮の比率を揃えるかを設定できるので、機械的にスライドするような動きだけでなく柔らかな表現もできます。
例えばSDは、前に腕を突き出している感じを出すために、腕の長さを短くしたりすることがありますが、上腕に「圧縮」「ストレッチ」を有効にしたIKを設定することで、前腕を動かすだけで、回転だけでなく長さも連動した腕を作ることもできます。
他にも複数のキャラクターが触れ合っている構図や、ウェイト調整だけではどうしても綺麗にならない複雑なパーツの繋ぎ目の調整など、活かせるケースはちょくちょくあり、度々助けられています。組み込み時も特にベイクせずに、そのままIK設定を持っていくことができます。この強力なIKコンストレイント機能は、Spineの強みだなと感じています。
パス・コンストレイント
パスをベジェで書き、そのパスとボーンにパス・コンストレイントを設定すると、そのパス上を通るようにボーンを動かすことができます。
曲線軌道の動きは、ボーンの移動だけでは綺麗に作れないので、マストで使う必要があります。
上図はその場で羽ばたく雀を作り、それにパス・コンストレイントを設定して「位置」を変更して移動させています。
他にも弓のようにしなるものなども、パス・コンストレイントを使うことで綺麗に表現することができます。
ANIMATEモードでのTips
調整トグル
「調整」を有効にすると、選択したキーを一括で回転や位置、拡縮などを調整できます。
メッシュツール
メッシュの頂点をクリックすると通常は単独選択ですが、ビューから「メッシュツール」を開き「ソフトセレクション」を有効にすると周りの頂点もやんわりブラシのように選択される状態になります。
再生
エディタ上で再生するFPSを変更したい場合はビューから「再生」を開き、ここで変更します。
APIと連携する際のTips
トラック
Spineには「トラック」という1つのスケルトンで複数のアニメーションを合成しながら再生できる機能があり、これがかなりの可能性を秘めています!エディタでは「プレビュー」ビューで確認することができます。
トラック1つにつき1つモーションを設定することができ、トラックのインデックスが増えるにつれてどんどん上書きする形で、モーションを「アルファ」の比率で合成することができます。それぞれのトラックは独立してループできるので、尺の違うモーションを合成することもできます。
例えば、雲が流れるモーションなどゆっくり動かしたいものは尺を数分ほど取る必要がありますが、トラックで分けて合成することで、他のモーションは短い尺のままでも、どちらもループさせることができます。
APIとの連携
addAnimationなどアニメーションを登録するメソッドの1つ目の引数で、トラックインデックスを指定できます。
spineIns.animationState.addAnimation(trackIndex, 'animation_name', isLoop, delayTime);
Live2Dのパラメータのような方向別の変形を実装側で制御したい場合は、直接コントロール用のボーンを動かす方法もありますが、方向別にトラックでアニメーションを設定してアルファを調整するのが、基準値や最大幅が分かりやすくてベターかと思います。
spineIns.animationState.tracks[trackIndex].alpha = alpha;
スキン
Spineには敵の色替えのような、一括で画像を切り替えるスキンという機能があり、複数のスキンを同時に適用することもできるのですが、通常は1つのスキンしか設定できません。エディタで複数適用スキンを確認する際は、ビューから「スキン」を開き、表示したいスキンにピンを打つことで複数スキンを適用した状態で表示できます。
イベント
Spineはモーション中にイベントを叩くことができます。
APIとの連携
下記は斜め向きのSDで、右向きは左向きのスケルトンを一括左右反転した上で、右向き用のスキンに切り替えて表示するという仕様で、モーション中にそれをイベントで切り替える例です。
あらかじめ実装側で顔の左右向きと体の左右向きを組み合わせたスキンを作っておき、反転させるイベントが叩かれたタイミングで、それを切り替えることで、そのモーションを左右向きどちらで使っても正しい画像を表示させることができます。
el.spine.animationState.addListener({event: function(t,e) {
if (e.data.name !== 'flipHead' && e.data.name !== 'flipBody' && e.data.name !== 'next') {
return;
}
if (e.data.name === 'flipHead') {
el.spineCurrentRight[0] = ~el.spineCurrentRight[0];
} else if (e.data.name === 'flipBody') {
el.spineCurrentRight[1] = ~el.spineCurrentRight[1];
} else if (e.data.name === 'next') {
el.spineCurrentRight = [0, 0];
}
el.spine.skeleton.setSkin(dirSkin[-el.spineCurrentRight[0]][-el.spineCurrentRight[1]]);
el.spine.skeleton.setSlotsToSetupPose();
}});
その他便利ツール
Spine Web Playerはフレームの更新など細かいことを考えずに、SpineがWebで簡単に表示できて、かつAPIで制御できるので、モック制作にちょくちょく使っています。
Unityで特定のスロットでスケルトンを分割することのできる「SkeletonRenderSeparator」や、組み込みファイルを表示するユーティリティソフトの「Skeleton Viewer」、それに内包されている制作したもののSpineのバージョンを下げられる「JsonRollback tool」の存在も知っていると役立つかと思います。
さいごに
これまでSpineを使ってきて、便利に使っている機能や、知っててよかったと感じた機能を中心に紹介しました。Spineでできることはこれが全てというわけではないので、より知りたい方は公式ドキュメントをぜひ読んでみてください。
Spineは熱心に更新が続けられていて、次の3.9-betaでは、現状の隣り合ったキーフレーム2点間の変位しか調整できなかったグラフビューを置き換える形で、待ちに待ったカーブエディタを実装することが予告されており、とても楽しみです!
では、明日以降のQualiArts Advent Calendar 2019もよろしくお願いいたします!
(注釈)
※1:この記事のエディタの画像は3.8のものですが、実際のプロダクトでは2019年現在まだ3.8は使用しておらず、3.7以前のバージョンを使用しています。
※2:実際のプロダクトのコードとは違います。
※3:最新Verの日本語表示では「設定」になってしまいました;;分かりづらくなってしまって悲しいです…
※4:日本語表示の「アニメ化」ってもはや別の意味では…