【Unity】LWRPで、壁で遮られて見えないキャラクターをシルエット表示するのが超簡単にできた
壁で遮られて場所が分からないキャラクターのシルエットを表示するアプローチを、LWRPでノーコーディングで実現出来たので紹介します。
- 壁に隠れてキャラクターが見えない問題
- Custom Forward Renderでシルエットを描画してみる
- 手順1:Custom Forward Rendeのセットアップ
- 手順2:Characterレイヤーに所属するモデルが壁の裏に回った時にシルエットを表示する
- 手順3:シルエット描画後にキャラクターを表示する
- 特許
- 関連
壁に隠れてキャラクターが見えない問題
今回Survival Shooterのステージだけを差し替えてみる的なのを試した所、ステージ手前のオブジェクトがキャラクターを隠してしまい、何処に敵がいるのかを見つけられなくなりました。お陰で理不尽にゲームの難易度が上がり、思ったほど面白くなくなるといった事がありました。
このカメラ問題の回答は色々と模索されています。例えば手前の壁を透明にする。他にもカメラの位置を上に持っていく(Cinemachine の Clear Shot)、向きは自由に変えられるので見えなくなるのは自分のせい等。今回はLWRPで面白い回避方法がGDCで紹介されていたので、それを試してみます。
Custom Forward Renderでシルエットを描画してみる
LWRP 5.7から、 Custom Forward Render
を使用出来るようになりました。これで特定のレイヤー(or 描画タイプ・シェーダーパス)に所属するモデルの描画をオーバーライドしたり、描画するタイミングを変更したり複数回描画するといった事が実現出来るみたいです。
今回はソレを利用して、シーン上に表示されているプレイヤーと敵キャラクターのシルエット表示をやってみます。
今回やる理屈は、下のような内容です。
- Playerのレイヤーに所属するオブジェクトの、壁より奥(塗るピクセルのZ値がZバッファより大きい)の部分を、マテリアルをオーバーライドして塗る
- Playerのレイヤーに所属するオブジェクトの、壁より手前(塗るピクセルのZ値がZバッファより小さい)の部分を、普通に描画する
手順1:Custom Forward Rendeのセットアップ
最初にCustom Forward Rendeをセットアップします。
Assets -> Create -> Rendering -> Lightweight Render Pipeline -> Forward Render
で、Forward Render Asset
を作成- LWRP Assetの
General -> Renderer Type
をCustom
に変更 - LWRP Assetの
General -> Data
に、先ほど作成したForward Render Asset
を設定
手順2:Characterレイヤーに所属するモデルが壁の裏に回った時にシルエットを表示する
上のように、キャラクターのシルエットを表示します。
Forward Render Asset
のRender Features
の+ボタン
を押しRender Object
を選択Filters -> Layer Mask
でPlayer
を選択Overrides
のMaterial
をシルエット表示用のマテリアルに変更Overrides
のDepth
にチェックを入れ、Depth Test
をGreater
(大きい)に変更
これで、塗るピクセルより手前にZ値が書かれている場合(モデルがある場合)、Overrides
で指定したマテリアルで描画されます。
ただし、今の設定だと「Playerが遮蔽した物もシルエットとして表示」されてしまっています。例えば下の画像のように、壁からのシルエットだけでなく銃のシルエット、そして他のPlayerからのシルエットも表示されてしまっていて、余り良くないです。
手順3:シルエット描画後にキャラクターを表示する
シルエットの描画後にキャラクターを表示するように変更します。
まず、Forward Render Assetの設定を変更して「Characterのレイヤーが設定されているモデルを、標準では描画しない」ようにします。 下の設定を行うと、Forward Render Assetで描画した分のみ表示されるようになります。
Forward Render Asset
のDefault Layer Mask
からCharacter
を抜く
次にシルエットを描画した後に明示的にCharacterレイヤーのモデルを表示します。
Forward Render Asset
のRender Features
の+ボタン
を押しRender Object
を選択Filters -> Layer Mask
でPlayer
を選択
これで、ステンシル描画後にキャラクターが描画されるので、キャラクターが期待通りに表示されます。ついでにキャラクター同士が被った場合もシルエットになりません。
なお、コレを応用するとプレイヤーと敵の色違いのシルエットとかも出せます。手順2で敵用のシルエットを描画して、手順3で描画する対象に敵も含めるだけ。
特許
この割と海外のゲームでよく見る「壁の向こうのキャラクターのシルエットを表示する」表現は、特許が既に登録されています。ご利用は計画的に
関連
2Dで、シルエットではなく手前のステージを消すタイプ