【Unity】ポストプロセスでピンチ表現を実装する
製作中のローグライクゲーム『ローグスフィア』では、HPが少なくなったときのピンチ表現にポストプロセス(PostProcess)を使用しています。
この程度の表現であれば、普通にSprite画像を重ねて表示するだけでもよく、わざわざポストプロセスを使わなくても良かったのかもしれませんが、今まであまり使ったことがなかったのでちょっと使ってみたかったんですよね。いろいろなトラブルにも遭遇したので、手順の備忘録を残しておきます。
1. ポストプロセス のインストール
昔は ImageEffects が Unity に同梱されていた気がするのですが、最近は Post Processing Stack を Asset Store から別途インストールするようです。
ダウンロードして Unity に import しましょう。
2. ピンチ表現の設定 (Vignette)
Post Processing Stack を使えば、ぼかしだったり明るさ調整だったりと様々な表現ができるのですが、今回のピンチ表現には Vignette(ビネット)という画面の周辺を暗くする技術を使いました。
2-1. プロファイルの作成
Post Processing Stack ではどんな効果を適用するかをプロファイルと呼ばれるもので定義するようです。Project Viewの好きな場所で、「右クリック」 > 「Create」 > 「Post-Processing Profile」 で作成できます。
今回は「DangerHpGuideSettings」と「DangerHpUISetting」の2個のプロファイルを作成しました。ローグスフィアの場合、UIレイヤーより上のレイヤーと下のレイヤーの2箇所でビネット効果を使うことで、画面の周囲を赤くするピンチ表現を実現しています。
2-2. プロファイルの設定
作成したプロファイルを選択し、Inspector上で「Vignette」のチェックボックスにチェックをつけて、色や円の大きさ等を設定します。
[DangerHpGuideSetting] 下レイヤー
[DangerHPUISetting] 上レイヤー
2-3. カメラオブジェクトに PostProcessingBehaviour をアタッチ
ビネット効果を付けたい Camera オブジェクトに Post Processing Behaviour スクリプトをアタッチし、アタッチしたスクリプトの Profile フィールドに先ほど作成したプロファイルをドラッグします。
今回のピンチ表現だと下記のような感じの設定です。
・UIを描画するカメラに Post Processing Behaviour をアタッチして「DangerHPUISetting」プロファイルをドラッグ
・UIの背面を描画するカメラに Post Processing Behaviour をアタッチして「DangerHpGuideSetting」プロファイルをドラッグ
2-4. Post Processing Behaviour の チェックは外しておき、スクリプトで制御する
初期状態ではビネット効果は使用しないので外しておきます。
あとはゲームのソースコード内で、HPが少なくなったら PostProcessingBehaviour のenabled プロパティを true にする実装をして完了です。
3. ビルドでフリーズする問題
Editor上では全く問題なかったのですが、Androidビルドを作成する際に毎回同じ場所で処理がフリーズして固まってしまいました。時間がかかっているのかなと思い1時間ぐらい待ってみましたが、下記の状態からまったく進まず・・・
Packaging assets - 85a45a6d8b2ffb84987d2b028ecfb220
何が原因なのか全然わからなくて(おそらく後述する問題だったのですが)、苦し紛れに Unity のバージョンを 5.6.4f1 から 2017.3.0f3 にアップデートし、さらに Post Processing Stack を最新版にアップデートしたところ、10分ぐらい待てばビルド処理が進むようになりました。
4. 処理落ちがひどい問題
ビルドは作れたものの、実機(Nexus5 Android4.4)上で確認したところ、ピンチ表現のポストプロセスを表示する際に明らかに処理落ちしてました(1〜2秒処理が固まってから画面が赤くなる感じ)。
https://forum.unity.com/threads/post-processing-stack-cannot-build-android-on-mac.484019/
上記にもあるのですが、Post Processing Stack のデフォルトのままだと大量のシェーダーバリアントが作られるみたいです。ちなみに、シェーダーバリアントって何か調べたのですが、この辺り前提知識がなさすぎてイマイチよくわからず...
とにかく、プロジェクトビューの 「PostProcessing」 > 「Resources」 > 「Shaders」> 「Uber」を選択し、Inspector上の Compiled Code の ▼部分を押すとバリアントの数を確認できます。
2.59k なので 2590 個もある...
今回使用しているのはビネットだけなので、Uber.shader のソースを開いて、
#pragma multi_compile __ UNITY_COLORSPACE_GAMMA
#pragma multi_compile __ CHROMATIC_ABERRATION
#pragma multi_compile __ DEPTH_OF_FIELD DEPTH_OF_FIELD_COC_VIEW
#pragma multi_compile __ BLOOM BLOOM_LENS_DIRT
#pragma multi_compile __ COLOR_GRADING COLOR_GRADING_LOG_VIEW
#pragma multi_compile __ USER_LUT
#pragma multi_compile __ GRAIN
#pragma multi_compile __ VIGNETTE_CLASSIC VIGNETTE_MASKED
#pragma multi_compile __ DITHERING
ここの部分を全部コメントアウトして、
こんな感じに、ビネット(VIGNETTE)のCLASSICだけ定義するように書き換えたところ、
2個だけになりました・・・・!
この状態で端末確認したところ、ビルド時間も早くなり処理落ちも緩和されました。
参考記事