0 支持
228 閲覧
(120 ポイント) Q&A
カテゴリーを変更

動作環境

  • Unity 2018.2.16f
  • SpriteStudio6 Player for Unity Version: 1.1.0
  • SpriteStudio Ver6.2.2
  • macOS 10.14.4

SpriteStudio6 PlayerモードでsspjをUnityにインポートし、開発をしております。

ベースとなるsspjのprefabにはNULLパーツが含まれています。

このNULLパーツの子として、異なるsspjからインポートしたprefabを追加することで、キャラクターの見た目を変えるようなゲームを開発中です。

Script_SpriteStudio6_RootのOrder in LayerによってNULLパーツの描画順序を管理していたのですが、アニメーションフレームごとに描画順序を変更したく、Order in Layerではなくベースとなるsspjのアニメーションに設定されている優先度を利用したいと考えております。しかし、単純に子として追加しただけでは優先度が反映されず、描画順がめちゃくちゃになってしまいます。


質問したい点ですが、

1.UnityにおけるNULLパーツの使用方法は上記の使い方であっていますでしょうか?

2.ベースとなるsspjのNULLパーツに設定された優先度を、NULLパーツの子として追加されたsspjのprefabに反映することはできますか? (できない場合はNULLパーツをどのように利用すれば可能になるかご教授いただけると助かります)

よろしくお願いいたします。

このページをシェアする

回答 1

0 支持
(1.7k ポイント)
編集

t.yamamoto 様

お世話になっております。SS6Player for Unity担当です。

ご質問に回答させていただきます。


> 1.UnityにおけるNULLパーツの使用方法は上記の使い方であっていますでしょうか?

ご使用の方法はあっております。ご安心ください。

NULLパーツのメジャーな応用方法のひとつです。


> 2.ベースとなるsspjのNULLパーツに設定された優先度を、NULLパーツの子として追加されたsspjのprefabに反映することはできますか?

これについては、端的に言ってしまうと「できません」となります。

SpriteStudioの「優先度」は、「そのアニメーションの中だけで適用される」ため、そのアニメーション以外のアニメーションと状況を共有することはできません。

※これは、「インスタンス」アニメーションを使用した時に、親アニメーションと子アニメーションの優先度が同じ空間にない(子アニメーションは子アニメーションの中で優先度が処理された結果、親アニメーションで指定される優先度で1パーツとして表示される)……というのと同じです。

> できない場合はNULLパーツをどのように利用すれば可能になるかご教授いただけると助かります。

これについては、いくつか方法は考えつきますが……メジャーな方法は2つ(+2つ)かと思います。

  1. ユーザーデータに(優先度を切り替えるタイミングで)Order In Layerの値を入れて、それをプレーヤーの「ユーザーデータ」コールバックで受け取って、Order In Layerを変更する。
  2. NULLパーツのZ座標を使う
  3. (NULLパーツを使わずに)子のアニメーションがアニメーションをしないものであるなら、(別アニメーションにしないで)動的セル変更を使って変更してしまう。
  4. (NULLパーツを使わずに)差し替える子のアニメーションを「インスタンス」として使用する。

……最初に挙げておいて何ですが……1は推奨しません。

理由としては、「補間などがかけられない」「切り替えするパーツやフレームが増えてくるとランタイムでの再生が重くなる」という2点で、いささか扱い勝手が悪い……ということからです。

ですので、基本的には2の方法を推奨します。

ただ、これは、少しSpriteStudio6の操作で特殊な操作をする必要があります。

通常、SpriteStudio6でアニメーションのパーツのソート方法が「優先度」に設定されていると、Z座標のアトリビュートはグレーアウトして操作することができません。

ですので、Z座標をいじる時に、一時的にパーツのソート方法を「Z座標」に変更します(そうするとZ座標を操作することができます。ただし、見た目にパーツの表示順序が狂うと思いますが、データは壊れることはないのでご安心ください)。

目的とするZ座標を設定したら、再度ソート方法を「優先度」に戻すと、Z座標の値を保持したまま、再度Z座標がグレーアウトして操作できなくなります(そして表示順序は正しい状態に戻ったはずです)。

※Z座標は値が小さくなるほど手前になり・大きくなるほど奥になります。

SS6Player for Unityは、パーツソート方法が「優先度」のデータであっても、この「Z座標」のデータを(Unity上の)各GameObjectの座標に反映します。

※いささか裏技的なやり口ではありますが……この優先度の時でもZ座標を反映する……というのは、SS5Player for Unity(前のバージョンのSpriteStudio5用プレーヤ)の頃にユーザーの皆様からの要望で搭載された仕様であるのと・その動作互換性として(SS6Player for Unityでも)正規仕様となっています。

※Z値を反映したアニメーションをUnity上でX軸かY軸で回転させるとZ軸の差の部分でパーツがずれている結果になりますが、それを打ち消したい場合は、Script_SpriteStudio6_Root::FlagPlanarizationをtrueにすることで、描画上はパーツ毎のZ座標の差を打ち消すことが可能です。

この方法の欠点は下記になります。

  • 現在製作中のタイトルの各アニメーションの(Unity上での)プライオリティ制御をZ座標で行うように変更する必要があるかもしれません。
  • 親のアニメーションのパーツの間に子の(NULLパーツにぶら下げた)アニメーションを挟み込むようなプライオリティ制御はできない。

本来UnityはカメラからのZ座標でプライオリティを制御する(カメラに近いものほど手前に表示される)のが正道なのですが、特にUIなどでそれでは描画順序に不都合が起こる場合があり、それを解消するためにOrder In Layerでの「物理的な表示順序」を制御することができる……という感じになっています(あくまで「原則論」です)。

※このOrder In Layerのさらに上の優先度制御として、カメラの描画優先度設定によって、カメラを分けて……ということも併用できます。

そのため、Z座標での描画順序制御よりも、Order In Layerでの描画順序制御の方が強制力をもっている形になります(効果として「カメラの描画順序」>「Order In Layer」>「Z座標」という形になるはずです)。


3と4は亜系というか、ご希望の実装状態とは若干離れるかもしれないのですが、有効かもしれない方法なので提起させていただきました。

3は、「子のアニメーションがアニメーションしない(停止したもの)なら」の条件つきで成立する方法です。

子のアニメーションがアニメーションしない場合は、SS6Player for Unityの

Script_SpriteStudio6_Root::CellChangeParts関数を使用して、パーツが参照している参照セルをスクリプトから変更する……という方法があります。

https://github.com/SpriteStudio/SS6PlayerForUnity/wiki/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%EF%BC%88%5BRoot%5D%E3%82%BB%E3%83%AB%EF%BC%89#Function-CellChangeParts

4は、そのままインスタンスアニメーションを使用して作成しておいて

Script_SpriteStudio6_Root::InstanceChange関数を使用して、その「インスタンス」アニメーションのオブジェクトを差し替えるというものです。

この方法は、インスタンスが増えすぎると(通常のアニメーションと比較して)SS6Player for Unityの動作が重くなる……という点がデメリットとして挙げられます。

https://github.com/SpriteStudio/SS6PlayerForUnity/wiki/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%EF%BC%88%5BRoot%5D%E3%81%9D%E3%81%AE%E4%BB%96%EF%BC%89#Function-InstanceChange

また、子アニメーションのアニメーション制御がスクリプトからしづらい(Script_SpriteStudio6_Root::AnimationChangeInstance関数での制御以外はほぼできません)という点もデメリットかもしれません。

https://github.com/SpriteStudio/SS6PlayerForUnity/wiki/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%EF%BC%88%5BRoot%5D%E3%81%9D%E3%81%AE%E4%BB%96%EF%BC%89#Function-AnimationChangeInstance

※InstanceChangeは内部的に子のアニメーションを消して別のアニメーションをinstantiateするのでコストはかかりますが、恐らく想定されている処理でも類似の処理になる可能性が低くないため、アニメーション変更でのコストは似たようなパフォーマンスになるはずです。


大体上記のような内容になりますが、ご質問に適切な内容になっておりますでしょうか?

お望みの実装の一助となっていれば幸いです。

何卒今後ともよろしくお願いいたします。

(120 ポイント)
ご回答ありがとうございます。

どの方法も利用できそうです。大変参考になりました。
...