テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】LWRPで、壁で遮られて見えないキャラクターをシルエット表示するのが超簡単にできた

f:id:tsubaki_t1:20190415213647j:plain

壁で遮られて場所が分からないキャラクターのシルエットを表示するアプローチを、LWRPでノーコーディングで実現出来たので紹介します。

壁に隠れてキャラクターが見えない問題

今回Survival Shooterのステージだけを差し替えてみる的なのを試した所、ステージ手前のオブジェクトがキャラクターを隠してしまい、何処に敵がいるのかを見つけられなくなりました。お陰で理不尽にゲームの難易度が上がり、思ったほど面白くなくなるといった事がありました。

f:id:tsubaki_t1:20190415213803j:plain

このカメラ問題の回答は色々と模索されています。例えば手前の壁を透明にする。他にもカメラの位置を上に持っていく(Cinemachine の Clear Shot)、向きは自由に変えられるので見えなくなるのは自分のせい等。今回はLWRPで面白い回避方法がGDCで紹介されていたので、それを試してみます。

Custom Forward Renderでシルエットを描画してみる

LWRP 5.7から、 Custom Forward Render を使用出来るようになりました。これで特定のレイヤー(or 描画タイプ・シェーダーパス)に所属するモデルの描画をオーバーライドしたり、描画するタイミングを変更したり複数回描画するといった事が実現出来るみたいです。

今回はソレを利用して、シーン上に表示されているプレイヤーと敵キャラクターのシルエット表示をやってみます。

f:id:tsubaki_t1:20190415214846g:plain

今回やる理屈は、下のような内容です。

  • Playerのレイヤーに所属するオブジェクトの、壁より奥(塗るピクセルのZ値がZバッファより大きい)の部分を、マテリアルをオーバーライドして塗る
  • Playerのレイヤーに所属するオブジェクトの、壁より手前(塗るピクセルのZ値がZバッファより小さい)の部分を、普通に描画する

f:id:tsubaki_t1:20190416011400g:plain

手順1:Custom Forward Rendeのセットアップ

最初にCustom Forward Rendeをセットアップします。

  1. Assets -> Create -> Rendering -> Lightweight Render Pipeline -> Forward Renderで、Forward Render Assetを作成
  2. LWRP AssetのGeneral -> Renderer TypeCustomに変更
  3. LWRP AssetのGeneral -> Dataに、先ほど作成したForward Render Assetを設定

f:id:tsubaki_t1:20190415221348j:plain

f:id:tsubaki_t1:20190415221358j:plain

手順2:Characterレイヤーに所属するモデルが壁の裏に回った時にシルエットを表示する

f:id:tsubaki_t1:20190415222613j:plain

上のように、キャラクターのシルエットを表示します。

  1. Forward Render AssetRender Features+ボタンを押しRender Objectを選択
  2. Filters -> Layer MaskPlayerを選択
  3. OverridesMaterialをシルエット表示用のマテリアルに変更
  4. OverridesDepthにチェックを入れ、Depth TestGreater(大きい)に変更

これで、塗るピクセルより手前にZ値が書かれている場合(モデルがある場合)、Overridesで指定したマテリアルで描画されます。

f:id:tsubaki_t1:20190416233550g:plain

f:id:tsubaki_t1:20190415222923j:plain

ただし、今の設定だと「Playerが遮蔽した物もシルエットとして表示」されてしまっています。例えば下の画像のように、壁からのシルエットだけでなく銃のシルエット、そして他のPlayerからのシルエットも表示されてしまっていて、余り良くないです。

f:id:tsubaki_t1:20190415223544j:plain

手順3:シルエット描画後にキャラクターを表示する

シルエットの描画後にキャラクターを表示するように変更します。

まず、Forward Render Assetの設定を変更して「Characterのレイヤーが設定されているモデルを、標準では描画しない」ようにします。 下の設定を行うと、Forward Render Assetで描画した分のみ表示されるようになります。

  1. Forward Render AssetDefault Layer MaskからCharacterを抜く

f:id:tsubaki_t1:20190415224029j:plain

次にシルエットを描画した後に明示的にCharacterレイヤーのモデルを表示します。

  1. Forward Render AssetRender Features+ボタンを押しRender Objectを選択
  2. Filters -> Layer MaskPlayerを選択

これで、ステンシル描画後にキャラクターが描画されるので、キャラクターが期待通りに表示されます。ついでにキャラクター同士が被った場合もシルエットになりません。

f:id:tsubaki_t1:20190415224826j:plain

なお、コレを応用するとプレイヤーと敵の色違いのシルエットとかも出せます。手順2で敵用のシルエットを描画して、手順3で描画する対象に敵も含めるだけ。

f:id:tsubaki_t1:20190415230013j:plain

特許

この割と海外のゲームでよく見る「壁の向こうのキャラクターのシルエットを表示する」表現は、特許が既に登録されています。ご利用は計画的に

https://www.j-platpat.inpit.go.jp/web/PU/JPB_3637031/83F99CD3BABFA1C42D5F2FA913BC1CF9

関連

www.youtube.com

2Dで、シルエットではなく手前のステージを消すタイプ

tsubakit1.hateblo.jp