こんにちは、アプリケーション部の松田(@kimika127)です。
Unite 2017 Tokyo講演「「黒騎士と白の魔王」にみるC#で統一したサーバー/クライアント開発と現実的なUniRx使いこなし術」 - Grani Engineering Blog
先日のUnite 2017 Tokyoでも弊社CTOの河合が触れたものになりますが、今回は黒騎士と白の魔王(以下、黒騎士)のキャラクターの作りについてより詳しくお話をしようと思います。
Spine
まず、黒騎士ではキャラクターのアニメーションにSpineを全面的に採用しています。 みなさんのアバター、戦闘中に出てくる敵、マイタウンのスプリやリゼット等、全てSpineで作られています。
Spineにした理由は単純なもので、黒騎士の開発が始まった当初、Unityに対応していることは当然、その上で表現力や開発のしやすさなどを加味した結果によるものです。 現在はUnityからAnima2Dが無償で提供されており、Spineと同じく積極的な更新もされていますので、これから開発をされる方はAnima2Dも選択肢としてあげてよいと思います。
今回はこのSpineで作られた中でもホーム画面等で表示されるキャラクターについて説明しようと思います。
Spectacle
今回ご紹介するホーム画面等で表示されるキャラクターは、Spineの周りに多数のParticleSystemをまとい、タップをするとボイスを喋りながらアピールモーションをする機能です。
先ほどもお話した通り、黒騎士では各所でSpineが使われているうえ、それらの作りが細かく違っています。 例えば、アバターであれはジョブによる着せ替え機能があったり、敵であれば色味の変更や必殺技演出等、必要な要件が異なるからです。 このようなものを全て「Spine」や「キャラ」などで表現するとあいまいになってしまうので、これらを提供する機能群をまとめて「Spectacle」というコードネームで呼び、他と区別するようにしています。
SkeletonAssetの準備
ここは私の専門外ではありますが、キャラクターが動くまでの過程をご紹介します。
まず実際に動かすためにはイラストとアニメーションが必要になります。 最初にアートディレクターが指示書を作ります。 黒騎士ではキャラクターに進化という概念がありますので、イラストレータはその指示書を基に進化前、進化後の2点のイラストを用意します。 アニメータはそこからさらに「待機中」「アピール中」の2つのモーションが必要ですので、計4つのコンテを作成します。
イラストが仕上がると、次に動きを付けるためにイラストを分割します。
分割されたイラストはSpineに取り込まれ、アニメータの手によってボーンとウェイトメッシュによりコンテに従った動きが付けられます。
エフェクトを付ける
Spectacleの特徴はSpineで作られたアニメーションの周りを、パーティクルで飾り付けていることです。 実はアニメータがボーンを組み込む際に、パーティクルを表示する場所に隠れたボーンを組み込んでいます。 例えば以下の写真は杖の先端のボーンに、エフェクタが作成したパーティクルを表示しています。
各パーティクルは指定されたボーンに対して配置されます。
また、ルートボーンに対してCurvyを使用したトレイルが渦を巻くように配置されています。 普段は正面からしか見えませんが、これを上から撮影するとこのように見えます。
これらのパーティクルは動きに合わせた最適なタイミングで出現/消失が制御できるように、Spineのアニメーションタイムライン上でイベントを組み込んでいます。 各イベントはエンジニアとアニメータの間で、どのような名前にするか、どのようなパラメータが渡されるか等の規約があらかじめ決められています。 エフェクト001の出現タイミングだと以下のようなイベントがSpine上で設定されます。
SpectacleはSpineのSkeletonAssetに埋め込まれたボーン情報とイベント情報を読み込み、それに合わせてエフェクトの制御を行っています。
ボーンとエフェクトとイベントを関連付ける
さて、せっかくエフェクトを用意しても、それらがどのボーンに関連付けられているかを知らなければ配置することができません。 SpectacleではDBで定義されたマスタをクライアントに送信し、組み立てます。
重要なことは、各ボーンそのものにエフェクトの情報を直接持っていないことです。 ボーンの番号とエフェクトのPrefabの関連をマスタデータで仲介することにより、Spineで再度アニメーションを弄らなくても、エフェクトの差し替えが容易にできるようにしています。
子Spectacle
Spectacleはそのボーンの先に別のSkeletonAssetを表示することができます。 こちらのSpectacleの周りにいる犬、猫、小鳥は、すべて本体とは切り離された別のSpineです。
これらもまた、エフェクトと同じようにアニメータはSpectacleで表示することができます。
SpectacleEditor
さて、現在リリースされているSpectacleは全部で80体以上に及び、エフェクトはSpectacle1体に付き10個つくこともあります。 そしてこれはおそらく今後も追加がされていくことでしょう。
これだけのSpectacleを円滑に用意するためには、我々エンジニアが関与せず、アートディレクタのもとでイラストレータやアニメータの手ですべて行える環境が必要になります。
上記の工程のうち、
- 指示書の作成
- コンテの作成
- イラストの作成、分割 → Photoshop/sai/CLIP STUDIO/他
- アニメーションの作成 → Spine Editor
- パーティクルの作成 → Unity
ここまではエンジニアの手がかからないものです。
しかし、ボーンとエフェクトとイベントを関連付ける部分はDBを介しているので、何もしなければアニメータが使いやすいものとは言えず、ミスも起こるでしょう。 そこで、Unity上でボーンとイベント、エフェクトを関連付け、APIを通してDBへ保存するエディタ拡張を用意しています。
SpectacleEditorの役目は、ボーンとエフェクトとイベントの関連付けをアニメータが行えるようにすることです。
ただし実際にアニメーションを組み込み、エフェクトをまとわせて表示できる状態で再生したり、たくさんのSpectacleを並べて再生すると、アートディレクターがバランスの悪さを指摘することがあります。 そのため、SpectacleEditorでは再度SpineやPhotoshopを開かなくても微調整が行える機能を用意しています。
具体的には
- Spineのリサイズ
- Spineの上下左右の位置の調整
- Spineやエフェクトの反転
- 子Spectacleの深度調整、反転
- アニメーションごとのエフェクトの表示/非表示
です。 これらのデータはすべてDBに保存され、みなさんのお手元では調整されたものが表示されるようになっています。
ボイス
ボイスに関しては、全くの別ラインでの作業になっています。 黒騎士ではCRIを使用しており、Spineのイベントなどを使用せずともアピール開始時に再生処理を呼び出すだけで適切なボイスが呼び出されるように、サウンドエンジニアがミドルウェアを使い用意をしてくれています。
Spectacleの仕様要求と問題点の妥協点
Spectacleはその見た目から、ガチャで排出されるキャラとされるなど黒騎士でも重要な要素になっています。 当然、リッチな見た目への要求は大きく、中には大きな問題になってしまったものもありました。
最後にそれをご紹介しようと思います。
Spectacle for UI
Spectacleはホーム画面やバトル中の召喚演出の他にも、様々な場所で再生が行われます。 例えば
- マップ上の宝箱、ギフト、ガチャ等でのキャラ取得
- デッキ編成や強化、図鑑、進化でのキャラ表示
- ガチャ画面でピックアップ
などです。
詳細は割愛させていただきますが、黒騎士ではuGUIの上に厚いレイヤーを重ねた独自のUIシステムがあります。 このUIシステムとSpectacleを重ねて綺麗に表示させるためには、UI上にうまく組み込ませる必要があります。 そのため、メモリや描画に対する負荷の少ない一部のUI部分では、RenderTextureに一度投影し、RawImageとして取り扱っています。
ただしRawImageをそのまま描画するとエフェクトが正しく描画されないため、専用のシェーダを差し込むことでこの問題を回避しています。
エフェクトの裏への回り込み
Spineはメッシュを変形して表示させるのですが、元の画像の形により、実際の輪郭に比べポリゴンが大きくなることがあります。 以下の青いポリゴンを見ると、周りに大きく余白があることがわかります。
これは3Dでは起こらない問題ですが、黒騎士ではエフェクトがSpineの周りをトレイルが回っているため、奥にあるエフェクトをSpineの余白が透明に塗りつぶしてしまう問題が起こります。 そこでこちらも専用のシェーダを用意し、先に描画されたSpineの透明ピクセルをclipすることで、本来奥にあるはずのエフェクトが見えるようにしています。
ゆがみシェーダ
黒騎士の一部のSpectacleでは、より迫力を出すためにアピール時に波を打つようなゆがみシェーダを取り入れています。 以下の画面の、特に文字部分ではよく目立ちます。
これらのシェーダは基本的にShader Forgeによって作成されたものですが、iOS Metal環境でCameraのRectを弄ると正しくGrabTextureが取得できないという不具合があります。
この不具合は見た目がひどく崩れるので、黒騎士ではシェーダ側でCameraのRectが弄られている際は歪ませない、という苦肉の策を入れています。
アルファマスク化
Spineからエクスポートされる形式はいくつかありますが、黒騎士ではBinary+PNGで吐き出しています。 BinaryはJSONよりも読み込み速度が速いので、特にJSONにこだわらない限りはBinaryをオススメします。
さて問題は画像です。 Spectacleで吐き出されるPNGは主に1024x1024サイズになります。 これを黒騎士の仕様上、プレイヤー4人×召喚2枠=計8体を描画しなければいけません。 つまり、真っ先に削るべきはテクスチャのメモリ使用量という事になります、それもクオリティを下げない方法で。
黒騎士ではこの問題を解決するために、以下の形式をとりました。
- アルファマスクを使い、透明を含むテクスチャを2枚に分ける
- iOSはRGB Compressed PVRTC 4bitのBest画質
- AndroidはRGB Compressed ETC 4bitsのNormal画質
アルファマスクを使用したのは、透明ピクセルを含むテクスチャをPVRTCで圧縮すると画質が大きく下がってしまうためです。 また、Androidの画質がNormalなのは、Best画質にすると途方もない変換時間が掛かってしまい、AssetBundleを生成するCIがタイムアウトしてしまうためです。
アルファマスクを描画するためには、専用のシェーダを用意し、全てのSpine用マテリアルにアルファマスクを差し込み、画像の圧縮設定を行わなければなりません。 これも当然Spectacleの機能で自動化されており、読み込んだSpineから、右クリックのエディタ拡張を使用すると、クリック1回で
- アルファマスクの生成
- マテリアルに専用シェーダの設定
- テクスチャの圧縮設定の変更
- アセットバンドルの設定
をすべて一括で行うようになっています。 アルファマスクの生成では、元のPNGデータを壊さずに不透明データを生成するようになっています。
まとめ
以上のように、黒騎士では2D描画もかなりこだわって作っています。
演出のこだわりを達成するために私が大事だと思っていることは、エンジニアの手をできるだけ介さずに、アートディレクタ、イラストレータ、アニメータ、エフェクタの作業の、1から10までの流れを妨げないことだと思っています。 エンジニアは現在Spectacleにはほぼ関わっていない状態ですが、指示書から納品まで、求められるリリースサイクルに耐えうるチームができあがっており、アニメ部との協力体制と的確なフィードバックの賜物であると思っています。
今後も黒騎士と白の魔王を通じて、より良い体験を多くみなさんに届けられるように頑張っていきますので、よろしくお願いします。