大量のSD制作を支える「IDOLY PRIDE」におけるSpine活用事例② 〜アイテム付与/モーション合成編〜

はじめに
株式会社QualiArtsでUnityエンジニアをしている吉成です。2021年6月リリースの「IDOLY PRIDE」(以降、アイプラ)の開発に携わり、主にUnityでのゲーム開発やSD周りの設計を担当しています。
本記事は、3回に渡ってアイプラにおけるSpineの活用事例を紹介する記事の第2回目の記事です。
第1回目の記事はこちらをご覧になってください。
第2回目となる本記事では『アイテム付与/モーション合成編』として、キャラクターにアイテムを持たせるために行った工夫や、モーションを効率的に制作するために行ったモーション合成の方法の紹介を行います。
アイテム(小物)
アイプラには様々なアイテム(小物)が存在します。

これらのアイテム情報をキャラクターのSpineに入れるのは次の理由から厳しいです。
- 全アイテムを入れると、キャラクターのAtlasテクスチャを圧迫してしまう
- 常に全アイテムの情報をロードすることになるのでデータ量も増加してしまう
- 全キャラクターに同じアイテム情報を入れるのは冗長
- アイテムが増えるたびに全キャラクターのSpineが作り直しになる

そこでアイテムはキャラクターとは別のSpineとして作成します。

それにより先ほどの課題を解決することができます。
- キャラクターのAtlasテクスチャが圧迫されない
- 必要なアイテムしか生成しないので、デ ータ量も圧迫しない
- アイテム情報はアイテムのSpineに切り出されて重複しない
- アイテムが増えてもキャラクターのSpineに変更は入らない
そして、アイテムとキャラクターのSpineをそれぞれ生成し、重ねて表示をすることでアイテムを持っている状態を実現します。 この時、アイテム側にもキャラクターと同じ名前、同じ尺のモーションを用意し、同時に再生することで一緒に動いているように見せます。


しかし単純に重ねるだけだと限界があります。 キャラクターのSpineの中にアイテムを挟み込むことができないため、キャラクターとアイテムが互い違いに重なる時に破綻します。

SkeletonRenderSeparatorによる指定スロット分割
この課題はSkeletonRenderSeparatorを用いることで対応が可能です。 SkeletonRenderSeparatorを用いると、Spineで制作を行った際のスロット名で分割を行うことができます。
コードは次のようになります。
void SetSeparator()
{
// 指定スロットを境にキャラクターのSpineを分割
_characterSkeletonAnimation.FindAndApplySeparatorSlots((slotName) => slotName == "split_have");
_characterSkeletonAnimation.FindAndApplySeparatorSlots((slotName) => slotName == "split_back", false);
SkeletonRenderSeparator.AddToSkeletonRenderer(_characterSkeletonAnimation);
// 指定スロットを境にキャラクターのSpineを分割
_itemSkeletonAnimation.FindAndApplySeparatorSlots((slotName) => slotName == "split_have");
_itemSkeletonAnimation.FindAndApplySeparatorSlots((slotName) => slotName == "split_back", false);
SkeletonRenderSeparator.AddToSkeletonRenderer(_itemSkeletonAnimation, baseSortingOrder: 1);
}
}
Spineで制作を行う際に、分割を行いたい箇所のスロットを用意しておきます。
たとえば今回のアイテムでは、split_have
のスロットより上の部分は前髪などよりも前に突き出して表示をする部分、
split_have
とsplit_back
の間の部分は抱えこむようにして表示をする部分、
split_back
より下の部分は身体の後ろに表示をする部分、などのように分け られています。
この処理により互い違いに重ねられるように現状のSpineが分割されます。





また、分割前のHierarchy構造は次のようになっており、

分割後のHierarchy構造は次のようになります。

Hierarchyを見ても、元々キャラクターとアイテムで1つずつだったSpineのオブジェクトが複数に分割されていることが分かると思います。
SkeletonRenderSeparatorで分割を行った際には、分割されたそれぞれのオブジェクトにOrderInLayerの値が設定されます。
OrderInLayerの値はデフォルトでは0から順番に5ずつ振られていきます。
今回キャラクターではsplit_have
よりも上の前髪などの部分には10、split_have
とsplit_back
の間の身体などの部分には5、split_back
より下の影の部分には0が設定されます。
また、アイテムは引数でbaseSortingOrderで1を渡しているので、OrderInLayerの値はデフォルトでは0からではなく1から順番に5ずつ振られていきます。
そのため、split_have
とsplit_back
の間の浮き輪の手前の部分には6、split_back
より下の浮き輪の奥の部分には1が設定されます。
これにより、split_have
とsplit_back
の間の身体と浮き輪では浮き輪が手前に表示され、split_back
より下の影と浮き輪でも浮き輪が手前に表示されるようになります。
また今回は無いですが、前髪などよりも前に突き出して表示をしたいアイテムはsplit_have
よりも上に作成すれば、前髪よりも手前に表示されるようになります。
そして分割されたSpineを重ねて表示をすれば完成となります。
