ノーコーディングで手軽にアウトラインをつけてみる【Unity】

この投稿は[グレンジ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/grenge)の6日目の記事です。

# 概要
[株式会社グレンジ](https://www.grenge.co.jp/)でクライアントエンジニアをしているGamu([@AblerBiri](https://twitter.com/ablerbiri))です。

今回はUnityFx.Outlineを紹介したいと思います。

## 環境
OS : MacOS Big Sur(11.4)
Unity : 2020.3.12f1
URP : 10.5.0
UnityFx.Outline : 0.8.5

# UnityFx.Outline
UnityFx.Outlineは、3Dオブジェクトにアウトラインを付けられるプラグインアセットです。

https://github.com/Arvtesh/UnityFx.Outline

アウトラインをつけられるものは他にも沢山ありますが、UnityFx.Outlineの特徴は3つ挙げられます。

- 無料(Githubで公開されている)
- コーディング不要
- Built-in RPとURPに対応

特にURPでも手軽にアウトラインを試せるのは良いと思います。

# 導入手順
Unityのメニューから、Edit > Project Settingsを開きます。
次にPackage Managerタブに切り替えて、画像のようにScoped Registryの情報を入力して、保存します。

Name : Arvtesh
URL : https://registry.npmjs.org
Scope(s) : com.unityfx
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/9d4a448b-2132-8b85-0226-e8c766c8f47d.png">

Scoped Registryの追加が完了したら、次はUnityのメニューから、Window > Package Managerを開きます。
Packagesというプルダウンの項目をMy Registriesに切り替えて、画像のようにOutline toolkit(URP)を選択してインポートします。
URP側のパッケージをインポートすると同時にコアとなるOutline toolkitもインポートされます。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/0055d374-d05d-86c9-2f1a-fb71e4ddb292.png">

# Built-in RP
Unity標準のレンダーパイプライン(Built-in RP)を使用している場合は、オブジェクトごとに任意の幅と色のアウトラインを付けることができます。

まずはアウトラインを付けたいオブジェクトにOutlineBehaviourコンポーネントをアタッチします。
すると、画像のようなパラメータが展開されます。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/7f081b5c-5849-3e86-93d5-09264d3b029a.png">

アウトラインを調整したい場合は、Color、Width、RenderFlagsを調整すると良いです。

ColorとWidthだけ変更した結果はこのようになります。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/c3c58431-12f8-d14c-8cab-414ebb0606ef.png">

よくみると中央のCubeとQuadのアウトラインが互いに食い込んでしまっています。
これは、RenderFlagsのEnable Depth Testingを付けることで解決します。

全部のオブジェクトのRenderFlagsでEnable Depth TestingをONにした結果はこのようになります。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/d30a432b-8ec7-c589-ddec-77bdd82fe9c5.png">

# URP
UnityFx.Outlineの良いところの1つはURPもサポートしているところです。
しかし、こちらはオブジェクトごとではなくレイヤーごとにパラメータを調整します。

まずは、URPのForwardRenderer.assetを探します。
大抵の場合は、Assets/Settings/ForwardRenderer.assetにあります。

ForwardRendererのAdd Renderer Featureボタンを押し、Outline Featureを選択します。
すると、画像のようなパラメータが展開されます。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/19122c5d-f007-0af6-1658-3578c0cc0165.png">

このままだとアウトラインは描画されないのでパラメータを変更します。

Outline Filter Settingsのプルダウンを開き、Use Layer Maskを選択します。
すると、LayerMaskという追加パラメータが表示されるようになるので、そこでEverythingを選択します。
結果はこのようになります。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/fcba0b8e-1700-6648-8cbd-12588d7175e6.png">

確かにアウトラインが描画されたのですが、LayerMaskをEverythingにしたので全てのオブジェクトに対して描画されてしまっています。

床のPlane以外だけにアウトラインを付けるには、それらのオブジェクトのLayerをアウトライン専用のものにします。
画像のように、オブジェクトを選択してインスペクターのLayerのプルダウンからアウトライン専用のレイヤーを選択します。
もしレイヤーが無ければ、Add Layer...を押してレイヤーを作成することができます。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/04a0ff32-9776-e044-fb4f-eefe71a514b7.png">

このようにして床のPlane以外のオブジェクトのレイヤーをOutlineにし、先ほどForwardRenderer.assetで設定したLayerMaskをEverythingからOutlineに変更します。
これで床とそれ以外でアウトラインを分けることができました。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225590/4f6a3cdf-9088-a47e-2907-f442b5310d10.png">

# 最後に
3Dオブジェクトにノーコーディングでアウトラインを付けられるUnityFx.Outlineの使い方を紹介しました。
URP側の実装は制約が多いですが、アウトラインを試すくらいなら手頃で良いと思います。

明日は、島田さんの記事が投稿される予定です！

# 参考
https://github.com/Arvtesh/UnityFx.Outline
https://goods-tmu.blogspot.com/2021/06/unityurpd.html