Spine入門(Spineを採用するUnityプロジェクトのエンジニア向け)

# Spineを採用するUnityプロジェクトのエンジニア向け

この記事は、「Spineを採用するUnityプロジェクトのエンジニア」を対象としており、Spineの詳しい使い方よりは、Spineにどんな機能があり、どうスクリプトを書いたらいいのかについて着目して調査をしています。

## Spineとは

ゲーム向けに作られた多機能な2Dアニメーションソフトウェアです。同ジャンルとしてのソフトウェアとして

- Sprite Studio
- Sprite Builder
- Flash
- After Effect

などが挙げられます。しかし、FlashやAfterEffectでアニメーションを作成した場合、クライアントエンジニアがその演出をUnityで再現する必要がありますが、Spineを使用するとそのままUnityに取り込めるため、その必要がありません。また、Spineを導入した場合の利点は以下の通りです。

- 2Dアニメーションに必要な機能の充実度

|機能|説明|シチュエーションと利点|注意点|
|-----|------|------|-----|
|Skin|一体の「アニメーションキャラクタ」に多数の見た目を用意するための仕組み|エンジンで出力されるファイルサイズの節約やゲーム稼働中のメモリサイズを抑えるために利用される。アニメーションの共通化・atlasファイルの削減を図り、無駄なリソースと生産コストの削減が可能。|共通化を行うキャラクターは全て、パーツを同じ仕様(画像サイズや解像度など)で共通化して作る必要がある。|
|FFD|スプライトをメッシュ化、分割をし、動的にメッシュを変形させる機能。つまり、アニメーションに合わせて自動でパーツを変形させるなどが可能。|キャラクターのボディパーツだけではなく、布や紙のような柔らかい素材を滑らかに動かすことができたり、擬似3Dのような表現も行える。画像の数を減らすっことができるのでメモリの使用量も減る。|Pro限定の機能。また。実際の輪郭に比べポリゴンが大きくなることがある。|
|Event|アニメーション状に設定したキーフレームのタイミングでプログラム側へint、float、stringの変数を渡すことができる。|特定のモーション(ジャンプ等)を行なった際に、Spine側で設定したイベントをデリゲートを使用してフックを行い、動作をプログラム側でコントロールできる。開発効率が上昇する。||

- Exportできるデータ種類の豊富さ
- ライブラリの充実度

以下はSpineの公式サイトの紹介を抜粋したものです。

>Spineのプロセスはスケルタルまたはカットアウトアニメーションと呼ばれ、従来のフレームごとのアニメーションに比べ、以下の利点を提供する。

>- **小容量**　従来のアニメーションは各フレームに画像が必要だったが、Spineアニメーションは非常に小容量なボーンデータだけを保存する。このため、豊富でユニークなアニメーションをゲームに搭載することができる。
>- **アート要件**　Spineアニメーションは少数のアートセットのみを必要とするため、コストと時間を他のことに確保できる。
>- **スムーズ**　Spineアニメーションは補完を使用するため、アニメーションは常にフレームレートと同じくらいにスムーズとなる。また、品質を損なうことなくスロモーションも可能である。
>- **アタッチメント**　ボーンに装着される画像は様々なアイテムやエフェクトとともにキャラクターに設定することができ、簡単に交換できる。アニメーションは外見が違うキャラクターに再利用可能で、時間を節約できる。
>- **ミキシング**　アニメーションをブレンドすることができる。例えばウォーキング、ランニング、水泳アニメーションを再生しながら、射撃するアニメーションを再生することができる。1つのアニメーションから他のアニメーションにスムーズにクロスフェードすることができる。
>- **プロシージャルアニメーション**　ボーンはコードによって操作が可能で、マウスの位置に向かって射撃する、近くにいる敵を睨みつける、丘を駆け上がる時に前のめりになるなどのエフェクトを可能にする。

## とりあえず使ってみる。

Spineの体験版をインストールしては見たけど、体験版だとエクスポートができないらしいので、軽く触って見て「大体こんなもんか〜」ってところまでにしておきました。では、次は作ったアニメーションをUnityにどう入れるかについてメモしておきます。

### Unity側で事前準備

まずはSpineでエクスポートしたデータをUnityで使用するために、以下からSpineのランタイムをインポートする必要があります。

http://ja.esotericsoftware.com/spine-unity-download/

その後、メニュー → Assets → Import Package → Custom Packageから、先ほどDLしたpackageファイルをインポートします。

### Spineでのエクスポート時の設定項目

データ形式をJSONにし、以下のチェック項目を確認します。

- Nonessential Data(不必要なデータ)：スケルトンをレンダリングする必要のない追加データがJSONに含まれます。これはJsonがSpineに再インポートされるときに必要なデータです。ファイルの容量が多少増えます。
- Pretty print(きれいなプリント)：JSONは綺麗にフォーマットされ、人間が容易に読めるようになります。ファイルの容量が多少増えます。
- Create atlas(アトラス作成)：スケルトンにより使用されるイメージがテクスチャアトラスにパックされます。

### Sceneへの配置

この後、Unity側からエクスポートを行なったSkeletonデータをSceneにD&Dを行うことで、配置することが可能です。オブジェクト化時に方法が二つ表示されます。尚、オブジェクト化してもアニメーションは再生されません。

- SkeltonAnimation：Spineで生成されたアニメーションを簡単に再生するオブジェクトが生成される。
- Mecanim：Mecanim対応のオブジェクトが生成される。

Mecanimに関しては以下の記事に調査メモを綴ってます。
(執筆後、リンク貼ります。)

### Inspectorの設定

体験版ではエクスポートができないため、スクショはありませんが、Skeleton Animationの要素に関する説明をメモ書きしておきます。申し訳なす。

|要素|説明|備考|
|-----|-----|------|
|Skeleton Data Asset|コンポーネントの対象となるSpineのデータ||
|Initial Skin|現在設定されているスキン|初期はdefault。Spine側で複数のスキンを作成した場合は、ここで項目を変更することができる||
|Sorting Layer|レンダリングの際に前後関係を定義するレイヤー||
|Order in Layer|レイヤー中での前後関係。小さい番号ほど先に描画され後ろになり、大きい番号が後から描画され前面に出る||
|Render Meshes|メッシュをレンダリングするか||
|Immutable Triangles|画像の交換/隠蔽をしない場合にチェックする|スケルトンレンダラーで大量の配列ジャグリングを省くことができる|自信ない|
|Calculate Normals|法線の計算を行う|Spineのアニメーションを点灯させるのに使用？|
|Calculate Tangents|接線の計算を行う|
|Front Facing|特定の要件を持つライトシェーダー専用|自信ない|
|Submesh Separators|わかりませんでした！多分自身に武器スロットを作っておいて、スケルトンには含まれていない通常の単一スプライトを取り出し、sortingとorderの間のレイヤーにあるメッシュに挿入できそうな感じです。武器の画像切り替えに使用できそうです。|詳しい方いたら教えてください。|
|Animation|再生したいアニメーションを設定する|再生ボタンで確認できる||
|Loop|ループ再生にするか否か||
|TimeScale|アニメーションの再生スピード||

## Scriptでの制御方法

SkeltonAnimationの場合はプログラムでアニメーションを制御を行います。スケルトンのアニメーションを実際に制御するクラスは、Spine.AnimationStateです。SkeletonAnimationもこのクラスを中心に構築されています。このSpine.AnimationStateのインスタンスをAwake時点でインスタンス化し、参照をSkeletonAnimation.stateに格納しています。

AnimationStateは、より低レイヤーでアニメーションの更新、キューイング、レイヤー、ミキシング/クロスフェーディングを管理します。

例えば、

```C#:test.cs
void Start ()
{
    SkeletonAnimation charaAnim =
        GetComponent<SkeletonAnimation> ();
    Spine.AnimationState charaState = charaAnim.state;

    // SetAnimationでアニメーションの変更
    // 引数：Track(後述)、アニメーション名、ループ再生か否か
    charaState.SetAnimation (0, "Idle", true);

    // アニメーション終了後処理
    charaState.Complete += (処理);

    Spine.Skeleton charaSkel = charAnim.skeleton;
    charaSkel.SetSkin ("スキン名");
    // スキン変更後は必ず呼ぶ。
    //　SkeletonDataのSlotDataリストの値を使用して、スロットをsetup poseに設定する。
    charaSkel.SetSlotsToSetupPose ();
}
```

これらコードの記述に関しては公式ドキュメントを読むことをお勧めします(英語しか見つからなかったので、日本語版を知ってる方は教えてください)。

### Track？

これは複数のSpineアニメーションを同時再生するアニメーションレイヤーです。

例えば、キャラの体が動くアニメーションを再生しながら、銃を持った腕のアニメーションを再生するようなシチュエーションに利用できます。

先ほどのコードではトラック0でアニメーション再生を行なっており、ここでトラック1に「Shot」のようなアニメーションを再生するコードを入れると、両方のアニメーションが同時に再生され、それぞれに設定されている再生期間に応じて終了またはループします。

数字が高いほど、高い優先順位を持ちますので、使用する際は注意してください。

## 参考

- [Getting Started (公式)](http://ja.esotericsoftware.com/spine-unity)
- [Outdated documentation (公式)](http://ja.esotericsoftware.com/spine-using-runtimes/)
- [オルタナティブガールズでのSpine導入と世界観に違和感を抱かせないゲームUX](https://www.cyberagent.co.jp/technicalcreator/article/id=12472)
- [2DスケルトンアニメーションとしてのSpineをUnityに導入するまでの流れ](http://kikki.hatenablog.com/entry/2015/06/08/123253)
- [UnityにSpineのデータを読み込んで操作する(Script編)](http://qiita.com/harayoki/items/f595c9d8d433b1d0ad71)
- [黒騎士と白の魔王のキャラクターの作りについて](http://engineering.grani.jp/entry/2017/05/16/214525)
- [Spineのスキン機能を使ってみる１](http://befool.co.jp/blog/udagawa/spine-skin-1/)
- [Spineランタイム：アニメーションの連続再生](http://qiita.com/harayoki/items/41865353c38b0c885080)
- [2Dアニメーションソフトウェア「Spine」のデータをUnityのMecanimで動かす(20150319追記)](http://qiita.com/Mavoroshi_Oni/items/9b997d7d8ed49fc809b1)
- [Spineでプロ生ちゃんに動いてもらう](http://qiita.com/Mavoroshi_Oni/items/5317f83b23fd76ef9b6b)
- [UnityでSpineを扱う際に覚えておきたいTIPS](http://qiita.com/kuuki_yomenaio/items/13432e5d912b6b62abdf)
- [Spineランタイム：アニメーションの再生スピードを調整する](http://qiita.com/harayoki/items/f87499e36a150938df2b)