選択できるオブジェクトにアウトラインをつける

# はじめに
この記事は[Life is Tech! Tokai Advent Calendar 2022](https://qiita.com/advent-calendar/2022/life-is-tech-tokai)の18日目の記事です。

一般的にアウトラインの実装方法は「ひと回り大きいオブジェクトを重ねて線を表現する」
というものですが、**正直面倒臭い!**
ということでUnity、URPで実装可能な方法を紹介します。
# 開発環境
- Unity 2021.3.6f1
- Visual Studio 2019
# Unityでの実装
### Unityプロジェクトの立ち上げ
最初の「新しいプロジェクト」から「3D(URP)」でプロジェクトを立ち上げます。
<img width="500" alt="スクリーンショット 2022-12-11 21.42.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3054106/2558902d-c2a5-e2df-6a54-8ac2ea61a4e8.png">
URPでの実装になるのでURPでない場合はURPを導入してください。別の方の記事ですが、こちらの[URP導入法](https://ny-program.hatenablog.com/entry/2021/07/10/154301)を参考にしてください。
### Unityプロジェクトのファイルを一部変更
プロジェクトファイルの中にある「Packages」=>「manifest.json」の中身を変更します。
以下を「{」の一行下に追加してください。これはunityfxが使えるようになり、URLで素晴らしい方が作ったアウトラインスクリプトをダウンロードします。
```
"scopedRegistries": [
    {
      "name": "Arvtesh",
      "url": "https://registry.npmjs.org/",
      "scopes": [
        "com.unityfx"
      ]
    }
  ],
```
以下を「"dependencies": {」の一行下に追加してください。
```
    "com.unityfx.outline": "0.8.3",
    "com.unityfx.outline.urp": "0.3.0",
```
追加した結果、こうなります。↓
```
{//一個目
  "scopedRegistries": [
    {
      "name": "Arvtesh",
      "url": "https://registry.npmjs.org/",
      "scopes": [
        "com.unityfx"
      ]
    }
  ],
//一個目終わり
  "dependencies": {
    "com.unityfx.outline": "0.8.3",//2個目
    "com.unityfx.outline.urp": "0.3.0",//2個目
    "com.unity.collab-proxy": "1.15.18",
    "com.unity.ide.rider": "3.0.15",
    "com.unity.ide.visualstudio": "2.0.16",
    "com.unity.ide.vscode": "1.2.5",
    "com.unity.render-pipelines.universal": "12.1.7",
    "com.unity.test-framework": "1.1.31",
    "com.unity.textmeshpro": "3.0.6",
    "com.unity.timeline": "1.6.4",
    "com.unity.ugui": "1.0.0",
    "com.unity.visualscripting": "1.7.8",
    "com.unity.modules.ai": "1.0.0",
    "com.unity.modules.androidjni": "1.0.0",
    "com.unity.modules.animation": "1.0.0",
    "com.unity.modules.assetbundle": "1.0.0",
    "com.unity.modules.audio": "1.0.0",
    "com.unity.modules.cloth": "1.0.0",
    "com.unity.modules.director": "1.0.0",
    "com.unity.modules.imageconversion": "1.0.0",
    "com.unity.modules.imgui": "1.0.0",
    "com.unity.modules.jsonserialize": "1.0.0",
    "com.unity.modules.particlesystem": "1.0.0",
    "com.unity.modules.physics": "1.0.0",
    "com.unity.modules.physics2d": "1.0.0",
    "com.unity.modules.screencapture": "1.0.0",
    "com.unity.modules.terrain": "1.0.0",
    "com.unity.modules.terrainphysics": "1.0.0",
    "com.unity.modules.tilemap": "1.0.0",
    "com.unity.modules.ui": "1.0.0",
    "com.unity.modules.uielements": "1.0.0",
    "com.unity.modules.umbra": "1.0.0",
    "com.unity.modules.unityanalytics": "1.0.0",
    "com.unity.modules.unitywebrequest": "1.0.0",
    "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
    "com.unity.modules.unitywebrequestaudio": "1.0.0",
    "com.unity.modules.unitywebrequesttexture": "1.0.0",
    "com.unity.modules.unitywebrequestwww": "1.0.0",
    "com.unity.modules.vehicles": "1.0.0",
    "com.unity.modules.video": "1.0.0",
    "com.unity.modules.vr": "1.0.0",
    "com.unity.modules.wind": "1.0.0",
    "com.unity.modules.xr": "1.0.0"
  }
}
```
変更は以上です。
### Unityでの操作
#### Unityを立ち上げ直し
まずUnityプロジェクトを立ち上げ直してください。開き直すことでOutlineパッケージがダウンロードされます。
#### レイヤーの変更
Unityを開くことができたら、
1. 適当なオブジェクトを選択
2. Inspectorから「Layer」
3. AddLayer...をクリック
4. 適当な列に「Outline」レイヤーを追加
5. アウトラインを実装したいオブジェクトを選択
6. InspectorからLayerをOutlineに変更

#### ForwardRendererの設定
プロジェクト内のForwardRendererにOutline機能を実装していきます。
1. 「Main Camera」のInspector内の「Rendering」=>「Renderer」を「0:URP-HighFidelity」にしましょう。右の画像を参考にしてください。
(後でURPを導入した方は「Project」=>「Create」=>「Rendering」=>「UPR Asset (with Universal Render)」で生成して設定してください。左の画像を参考にしてください。)
　　　<img width="200" alt="スクリーンショット 2022-12-12 13.43.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3054106/52a4fa7a-0c0d-1251-506f-6196b2aa50f1.png">　　　　　<img width="300" alt="スクリーンショット 2022-12-12 13.56.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3054106/6c38cd96-0687-3863-0a79-b13599e4069b.png">　
2. 「Project」=>「Settings」=>「URP-HighFidelity-Renderer」のInspectorの一番下にある「Add Renderer Feature」から「Outline Feature」を追加してください。
3. 「Name」を適当な名前に変え、「Outline Filter Settings」を「Use Layer Mask」に設定してください。
3. 「Layer Mask」を「Outline」に設定してください。

これで設定は以上です。ここまで設定するとLayerに「Outline」を設定したオブジェクトにアウトラインがつくと思います。色や太さなどはお好みで変えてください。
# 実装確認
画像のようになっていれば完了です。色は水色、サイズは10で実装しているので皆さんと少し違うかもしれません。![スクリーンショット 2022-12-12 14.16.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3054106/866e1590-1d77-4d54-7a0d-aea5d0080e68.png)
# 終わりに
URP環境下でしか実装できないのは少しデメリットではありますが、ちょっとした操作で簡単に実装できるためおすすめです！

アウトラインは探索ゲームなどよく使われるUIになります。非常に大切な機能になるのでぜひ実装してみてください。
くっきりとした線だけでなく少しポワポワした線を設定してあげるとオーラを纏っているようになるので色々応用が効くと思います！

今回初めて記事を書いたのですが、これから定期的に記事を書いていきます！
# 参考記事
今回は以下の記事を参考にしました。ありがとうございます。
スタジオレンガのブログ：[UnityのURPで３Dモデルのアウトライン表示をする](https://goods-tmu.blogspot.com/2021/06/unityurpd.html)
# おまけ
今のままではずっとアウトラインが表示されてしまうので画面の中心にオブジェクトが入った時だけアウトラインを表示する方法を軽く紹介します。
### はじめに
実装方法を色々考えた結果、当たり判定(物理)が一番簡単に実装できたのでそれを紹介します。他に何かいい方法があれば教えてください。
### 実装
1. カメラの中心に長く伸ばしたCubeを子オブジェクトとして設定します。
![スクリーンショット 2022-12-12 15.08.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3054106/5f1f0206-0c3d-a513-7d0c-fc1bc64d7c7a.png)
2. 長く伸ばしたCubeのInspectorの「Box collider」=>「Is Trigger」にチェックを入れましょう。
3. 長く伸ばしたCubeのInspectorの「Add Component」=>「Rigidbody」を設定し、「Use Gravity」のチェックを外しましょう。
3. 適当なオブジェクトを選択=>Inspector内の「Tag」=>「Add Tag」=>「+」=>「Outline」=>「Save」=>アウトラインを実装したいオブジェクトを選択=>Inspector内の「Tag」
=>「Outline」に設定
4. C#スクリプトを一つ作ります。中身は以下の通りです。


```php:OutlineObjectChecker.cs
using UnityEngine;
public class OutlineObjectChecker : MonoBehaviour
{
/// <summary>
///  当たったオブジェクトのタグが”Outline”だったらLayerを”Outline”に変える
/// </summary>
    void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.tag == "Outline")
        {
            other.gameObject.layer = LayerMask.NameToLayer("Outline");
        }
    }
    /// <summary>
    /// 離れたオブジェクトのタグが”Outline”だったらLayerを”Default”に変える
    /// </summary>
    void OnTriggerExit(Collider other)
    {
        if (other.gameObject.tag == "Outline")
        {
            other.gameObject.layer = LayerMask.NameToLayer("Default");
        }
    }
}

```
このスクリプトを長く伸ばしたCubeにアタッチしてください。
そうすると...

![Outline.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3054106/b89d9e07-5ed1-624a-79bb-2d05ca427d6d.gif)

出来ました！！