SpriteStudio / SS5PlayerForUnity

OPTPiX SpriteStudio 5 Player for Unity
http://www.webtech.co.jp/spritestudio/
MIT License
39 stars 15 forks source link

全般 異なるアニメーションの前後関係の制御について #120

Open ryooo opened 9 years ago

ryooo commented 9 years ago

お世話になっております。

異なるアニメーションを同時に再生する場合、Script_SpriteStudio_DrawManagerViewは1つにするべきなのでしょうか。 複数のアニメーションのz軸の間に、SpriteStudio以外のオブジェクト(UIパーツやパーティクルなど)を挟むように配置したいのですが、Viewを1つにするとrenderQueueによって順序が制御されアニメーションの間に挟み込むことができずに困っております。

また、数十から数百のSpriteStudioアニメーションを同時に配置したいのですが、viewを分けた場合にはRender Queue Offsetで調整しないと異なるアニメーションのパーツの前後関係が正しくなりません。 (全てoffsetが0の場合、アニメーション間でパーツが前後混ざって表示されてしまいます。)

このような場合、オブジェクトの挟み込みを行うためにviewを分けて、オブジェクトの前後関係に応じてRender Queue Offsetを個別に設定する形が適切な実装になりますでしょうか。

MasamiYitsuse commented 9 years ago

ryooo321様

お世話になっております。

SS5Player for Unityの現状(GitHub上のMaster=1.2.3/Develop=1.2.9)の仕様では、仰られる通り、アニメーションの間にUnityのネイティブオブジェクトや他アセットの表示オブジェクトを挟み込む場合には、挟み込まれる単位でScript_SpriteStudio_DrawManagerViewを分割する必要がございます。 ※(視錐台内で)間に挟み込むオブジェクトが不透明の3Dモデルで書かれている(Zバッファに深度が記録されている)状況下においてのみ、Viewを分けることなくZバッファによるプライオリティを考慮した描画反映が可能にはなっております。

オブジェクトの前後関係を考慮した値をRender Queue Offsetに設定する場合、アプリケーション側で視点からの各オブジェクトのZ値を計算して、(その値を使用するRenderQueueの値範囲に変換して)Script_SpriteStudio_DrawManagerViewクラスのpublic int OffsetDrawQueue(メンバ変数)に設定することで、各オブジェクトのプライオリティを制御することは可能です。 その際に、Unityの各描画レイヤーのRenderQueue値範囲を超えない設定にする必要がございます。 Render Queue Baseの設定によって値範囲はかわり ・Back Ground : 0~999(最終的なMaterial.renderQueue値範囲: 1000~1999) ・Geometry : 0~449(最終的なMaterial.renderQueue値範囲: 2000~2449) ・Alpha Test : 0~549(最終的なMaterial.renderQueue値範囲: 2450~2999) ・Transparent(Shader Settingも同) : 0~999(最終的なMaterial.renderQueue値範囲: 3000~3999) ・Overlay : 0~999(最終的なMaterial.renderQueue値範囲: 4000~4999) となります。


少々余談的ではありますが現在の仕様に至る経緯を説明させて頂きますと……

すでに既知のこととは存じますが、念のためScript_SpriteStudio_DrawManagerViewの一番の役割を説明させて頂きますと 「単一ないし複数のマテリアルを使用しているSS5からインポートしたアニメーション群を、各マテリアルの表示順序を守りつつ・ドローコールを最低限に抑える」 ための処理となります。

以前SS5Player for UnityのVer.1.0系(現在はVer.1.2系です)の頃は、各Rootパーツ毎でScript_SpriteStudio_DrawManagerViewの機能を(Script_SpriteStudio_PartsRootの内部機能として)実装していたため、各オブジェクト毎でプライオリティを制御できたのですが、その仕様ですと最低でも「出現させたアニメーションの数」だけドローコールがかかってしまう……という点に対して、皆様から「多数のSS5の表示オブジェクト間にまたがってドローコールを最小化してほしい」とのご要望を多くいただき、現在の仕様を(一旦の安定策として、Ver.1.1系から)採用しているという面がございます。 ※そのご要望等の残り香(さまざまな経緯を省いて、結果のみが残っているという意味合いです)が、当Issueの中の https://github.com/SpriteStudio/SS5PlayerForUnity/issues/95 ……に残っております。 ※上記Issueの中にある「トレードオフ」した内容が「SS5Player for Unityのオブジェクトと、他の描画アセットとの(容易な)共存状態」という形になったという経緯がございます。 ※Ver.1.0と同等のことをVer.1.1以降で行う場合、1つのアニメーションオブジェクトに1つずつScript_SpriteStudio_DrawManagerViewをつけてZ値でOffsetDrawQueueの値を操作する……という、上記の方法になります。

このScript_SpriteStudio_DrawManagerViewの処理が存在しない(Unityの内部機能のドローコール最適化機能に任せた)場合、全てがoffsetが0の場合と近似した状況・もしくはもう少し表示状況が不安定になり、(Zバッファ比較を行うことを前提に各使用マテリアル毎でメッシュバッチングされるため)各パーツでのテクスチャや合成方法などの順序が画面全体として守られないような状況が発生してしまいます。 ※一応、SS5のデータに半透明ピクセル(拡縮時のアンチエリアスなども含む)や、乗算・減算合成などの「書かれる順序が最終的なピクセル色に影響する」合成が使用されていない場合において、シェーダのZWRITEをONにすることで、ハードウェア上のZバッファ比較に任せてのプライオリティ制御が可能になります。


上記の理由から、本件は現状のSS5PUの泣き所の一つであることについて、お詫び申し上げます。

一応、本件については、現在今後のSS5PUのバージョンアップの際の改修実装内容の一つとして検討されている最中ではあります。 検討中の実装案の一つとしては、「Script_SpriteStudio_DrawManagerViewのドローコール最適化中に間に挟まるオブジェクト(を制御しているGameObjectについているスクリプト内の静的関数)に対して、使用すべきMaterial.renderQueue値をコールバックで通知するような構造などが案として挙がってはおります。

ですが、(扱いが複雑になることや・他のバージョンアップ内容との兼ね合いなども含めて)検討中であり・決定には至ってはいないため、対応を行うかや何時頃の実装になりそうかなどについて、現状明言できない状態です。 その旨大変申し訳ございませんが、何卒ご理解の程お願いいたします。


追伸: もし、「使用するアトリビュートに制限がある」「複数のテクスチャや合成方法をSS5の1つのアニメーションの中で使用していない」という状況での運用が可能である場合、 「Ss5Converter for Unity2D」 https://github.com/SpriteStudio3rdParty/Ss5ConverterForUnity2D という別アセットもあります。 こちらは、SS5のデータをUnityのネイティブのAnimationデータに変換し・運用することができるアセットです。 こちらは描画そのものは(SS5Player for Unityのように描画マネージャを別個に持たず)Unityの描画処理に全てを任せる形となっています。 そのため、(SS5PUと比較してSS5Cは)Unityの他のオブジェクト等との親和性を保ちやすいという利点がございますため、もし、SS5Cが運用条件に合うようでしたら、ご検討いただけますと非常に助かります。 ※SS5CとSS5PUの2つのアセットを一つのプロジェクトやシーンで併用することについては、ほぼ問題なく行えるはずです(ただし、アニメーションの再生方法や描画方法が異なるため、SS5CのデータをSS5PUで再生したり・その逆などの「相互互換性」はありませんので注意してください)。

ryooo commented 9 years ago

詳細を共有くださいましてありがとうございます。 内容について承知いたしました。 今回は上記ご説明いただいた内容を受けて実装いたします。

ryooo commented 9 years ago

お世話になっております。

下記の1行をコメントアウトすることで、マテリアルのrender queueを揃えることができるかと思います。 https://github.com/SpriteStudio/SS5PlayerForUnity/blob/c67ad058cb9c6d2f3e88ba643d103b0a23d1d145/Assets/SpriteStudio/ScriptLibrary/Library_SpriteStudio.cs#L1018

改修を行う場合は自己責任になると認識はしておりますが、こちらの改修を行った場合にどういった影響が予想されるか(どのようなアニメーションの設定を行った際に意図しない表示になるか)、情報がございましたらご教示願えますでしょうか。

優先度の高いListMeshのマテリアルほどRender Queueを大きくするような処理にみうけられますが、render queueの設定がなくともListMeshおよびDataMeshの優先順でMeshに順次コンバインされていくため、問題が発現するケースは稀なのかと考えております。 (現状実装しているアニメーションについては見たところ問題なく表示されている状態にございます。) ※ 前提として、Script_SpriteStudio_DrawManagerViewをアニメーションごとにアタッチしております。

MasamiYitsuse commented 9 years ago

ryooo321 様

お世話になっております。

仰られている通り、その位置で「描画優先度の高いメッシュが使用しているマテリアルのMaterial.renderQueueへの設定値をインクリメントして」おります。

その改造(この+1をしている行を注釈化して削除すること)は、恐らく実運用上ほぼ問題は出ないかとは思います。 (ほぼ杞憂と思われますが)想像し得る現象としては 使用マテリアル: A 使用マテリアル: B 使用マテリアル: A の順でメッシュが表示された場合に、最初と最後のマテリアルAを使用しているバッチング後のメッシュがUnity上でCombineされてしまう可能性があるかもしれません(Unityのバージョンや他のアセットとの運用状態で挙動がかわる可能性も「0ではないかもしれない」という範囲です)。

※ただ、都度(バッチングしたメッシュの)使用マテリアルをnewしているため・マテリアルのインスタンス(実体)が別になるので、今までの私の使用経験上では描画順で問題が起こる(Unity側での同一マテリアル使用メッシュのバッチングにひっかかってしまう)ことはほとんどないかと思われます。

この+1の処理については、表示順序の確実性を担保するために(慎重を期して)行っている処理ですので、もし実用上問題がなければ(ないしは+1しないことで得られるメリットがあるのであれば)外してしまっても大丈夫ではないかと思われます。

以上となります。 お忙しい中お手数ですが、何卒よろしくお願いいたします。

ryooo commented 9 years ago

MasamiYitsuse 様

迅速な解答をありがとうございます。 いただいた情報は、実装上の参考とさせていただきます。

こちらこそ、今後ともよろしくお願いいたします。

aki017 commented 9 years ago

:+1:

aki017 commented 9 years ago

ありがとうございます。 Unity標準のバッチングについては”DisableBatching タグ”を使用することで発生しないと思うのですがこちらについて設定していない理由等ありますでしょうか http://docs.unity3d.com/ja/current/Manual/SL-SubshaderTags.html

MasamiYitsuse commented 9 years ago

aki017様

お世話になっております。 DisableBatchingタグについては、設定をしていない理由は、

・バッチング機構をSS5PUが持っているので、使用する必要性がないと思われる(Unityのバッチングを使用しない形にして・SS5PUの描画マネージャも通さずに出力すると、順序としては正しく出るのですがドローコールが大変なことになることが予想される一方、SS5PUの描画マネージャでメッシュをまとめてしまっているために、Unity側を切る必要性が思いつかないという側面です)。

・一応Unity Ver.3.57以上がSS5PUの現状対応バージョンになっておりますが、本タグが(確か記憶に間違いがなければ)Ver.4系のどこからかの搭載だった記憶があり、そのため使用をしていない。

というのが、主な理由となりますが……実質上、(設定していない)特段何かの障害があるなどの理由はありません。

以上となります。 何卒よろしくお願いいたします。

aki017 commented 9 years ago

ありがとうございます

 ※ただ、都度(バッチングしたメッシュの)使用マテリアルをnewしているため・マテリアルのインスタンス(実体)が別になるので、今までの私の使用経験上では描画順で問題が起こる(Unity側での同一マテリアル使用メッシュのバッチングにひっかかってしまう)ことはほとんどないかと思われます。

これについて解決できる可能性があるかと思い尋ねましたが古いバージョンをサポートするために使用していないとのこと了解いたしました。

MasamiYitsuse commented 9 years ago

aki017 様

ご提案、ありがとうございます<マテリアルのインスタンスを都度newするのを回避 今後、Unityの対応バージョン範囲などが変更になる可能性もないわけではありませんので、その際の対応バージョン範囲によって調査と検証した上で、参考にさせて頂きます。

重ねてありがとうございました。