Unity AR Foundation で XR Interaction Toolkit を利用する

# はじめに
[AR Foundation](https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@5.0/manual/index.html)で、[XR Interaction Toolkit](https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@2.5/manual/index.html)を利用することに挑戦してみました。
AR Foundation　も 4系と5系で、クラス名など変更がありましたので環境構築から記載していきます。

# 環境
* Unity 2022.3.10
* AR Foundation 5.0.7
* Apple ARKit XR Plugin 5.0.7
* XR Interaction Toolkit 2.5.2

# 環境構築
## Unity Projectの作成
Universal Render Pipeline(URP)を利用してプロジェクトを構築していきます。
![スクリーンショット 2023-10-09 9.08.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/42f4e021-5f6a-5636-8447-afc497ab4c6e.png)

## iOSにスイッチ
「Switch Platform」をクリック
![スクリーンショット 2023-10-09 9.13.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/72027f10-2695-7cb4-d686-91d86867a337.png)

## Project Settings の 「Player」の修正
* Company Name
![スクリーンショット 2023-10-09 9.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/f9ae765c-d216-8409-a6e7-214f2e37ac38.png)

* Override Default Bundle Identifier のチェックを外す
* Api Compatibility Level　を「.NET Framework」に変更
* Camera Usage Description : アプリを起動する際に表示されるカメラを利用する旨の説明文
![スクリーンショット 2023-10-09 9.17.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/8bfb2818-8410-13b5-879e-6c4d23097148.png)

## XR Plugin Management のインストール
「Install XR Plugin Management」をクリック
![スクリーンショット 2023-10-09 9.18.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/3f8a8401-06ec-45fb-2f86-fa45726a03ea.png)

## ARKit のインストール
ARKitをチェック
![スクリーンショット 2023-10-09 9.20.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/9156f637-44ea-723f-15ee-dd609ecb1590.png)

## Unity Editorの再起動
![スクリーンショット 2023-10-09 9.21.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/d6d2ff14-a0ab-81dc-f5b6-203aa737a24f.png)

## Face Tracking を利用する場合はチェック
![スクリーンショット 2023-10-09 9.23.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/e1d4cb4b-67b1-6bfc-49f8-9f5ca4c4ebb1.png)

## URPプロジェクトのための設定
### Project Settings の 「Graphics」の修正
* Scripting Render Pipeline Setting
![スクリーンショット 2023-10-09 15.11.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/a241574a-b61e-8f0c-4d1b-c10f6a89d7e6.png)

### Project Settings の 「Quality」の修正
* Levelsの「Balanced」をクリック
![スクリーンショット 2023-10-09 15.11.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/d0ba6307-664b-6c3c-d954-0b8c2f8351b1.png)

### Project　ウインドウ Assets > Settings の「URP-Balanced-Renderer.asset」の修正
![スクリーンショット 2023-10-09 9.50.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/061c4265-a5b5-0b79-a52d-e167dade4557.png)

「Add Renderer Feature」をクリックして、「AR Background Renderer Feature」を追加
![スクリーンショット 2023-10-09 9.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/a661ba9e-55e9-802e-1149-2ad93fc3b006.png)

## XR Interaction Toolkit のインストール
:::note info
ARKitをインストールすることで、自動的にAR Foundationもインストールされる
:::
XR Interaction Toolkitの「Install」をクリック
![スクリーンショット 2023-10-09 9.30.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/3e03c295-4b0e-8146-c688-a0d531900df6.png)

# シーン構築
## AR Session、XR Origin (AR) をシーンに追加
:::note info
XR Origin (AR) を追加するタイミングで、「XR Interaction Manager」も追加される
:::
![スクリーンショット 2023-10-09 11.36.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/df696686-ced8-1ce8-5f1a-c805b0f58e1a.png)
![スクリーンショット 2023-10-09 11.38.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/c5473f63-de60-f99a-955f-568df52ba5d5.png)

## シーン作成時に存在したMain Cameraを削除
:::note info
XR Origin (XR Rig) > Camera Offset に AR用の Main Cameraが存在するため、作成時のMain Cameraは不要
:::
![スクリーンショット 2023-10-09 11.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/ba1199a7-df7e-31da-1566-8cfe352d5eb2.png)

## Main Camera に「AR Gesture Interactor」を追加
![スクリーンショット 2023-10-09 11.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/5b74fef0-149a-145a-7b17-85d408dcf471.png)

* Interaction Manager に「XR Interaction Manager」を設定
![スクリーンショット 2023-10-09 11.45.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/e34ef21a-fe0d-9377-a0e2-63d71fccc664.png)

## XR Origin (XR Rig) に「AR Plane Manager」「AR Ray Cast Manager」を追加
平面に3Dオブジェクトを配置するために利用する
![スクリーンショット 2023-10-09 11.54.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/e1aa9a74-6d68-8b1e-ac2c-b110db69cbe0.png)

### 平面検知用の平面Prefabの作成
1. AR Default Planeを Hierachyウインドウに追加
1. Projectウインドウにドラック&ドロップすることで、Prafabを作成
1. HierachyウインドウのAR Default Planeを削除
![スクリーンショット 2023-10-09 11.57.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/9e00a6f8-73ec-5261-c138-d3171a2785a1.png)

## AR Plane Manager に 「AR Default Plane」を設定
![スクリーンショット 2023-10-09 11.59.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/6e812d07-b91e-ac85-6908-e6331f199956.png)

## XR Interaction Managerに「AR Placement Interactable」を追加

![スクリーンショット 2023-10-09 12.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/d9a74346-6176-597a-32b6-2e74fbd9c53f.png)

* Interaction Manager に「XR Interaction Manager」を設定
![スクリーンショット 2023-10-09 12.04.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/a7356d66-93c8-097c-d137-1e34b9b94bfb.png)

### タップで配置する3Dオブジェクトの設定とPrafab化
:::note info
オブジェクトに対して、コライダーの設置が別途必要です
:::
* AR Selection Interactable、AR Translation Interactable、AR Rotation Interactable、AR Scale Interactable を追加
![スクリーンショット 2023-10-09 12.18.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/976598a7-6f54-8c58-6647-6d2f326eb36c.png)

:::note info
AR Selection Interactable(選択/解除)、AR Translation Interactable(移動)、AR Rotation Interactable(回転)、AR Scale Interactable(縮小/拡大) と　Main Camera に設定したAR Gesture Interactor により、オブジェクトの選択、移動、回転、縮小・拡大が実現されます
:::
![スクリーンショット 2023-10-09 23.07.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/f6be5d99-272f-f6c6-8d6c-7cb070177d6d.png)

1. Projectウインドウにドラック&ドロップすることで、Prafabを作成
1. HierachyウインドウのPrefab化した3Dオブジェクトを削除を削除

## AR Placement Interactableに　タップで配置する3Dオブジェクトを設定
* Placement Prafab
![スクリーンショット 2023-10-09 23.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/f7408c23-e12f-7eb1-9827-3642cbef2c97.png)

## Interactionを試すスクリプトを作成
```csharp:XRInteractionSample.cs
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Interaction.Toolkit.AR;


public class XRInteractionSample : MonoBehaviour
{
    [SerializeField] private ARPlaneManager _planeManager;
    [SerializeField] private ARPlacementInteractable _placementInteractable;

    private GameObject _placedObject;
    
    private void OnEnable()
    {
        // イベントの登録
        _placementInteractable.objectPlaced.AddListener(ObjectPlaced);
        _placementInteractable.hoverEntered.AddListener(HoverEntered);
        _placementInteractable.hoverExited.AddListener(HoverExited);
    }

    private void ObjectPlaced(ARObjectPlacementEventArgs arg0)
    {
        if (_placedObject is not null)
        {
            Destroy(arg0.placementObject);
            return;
        }
        
        _placedObject = arg0.placementObject;
        
        ARSelectionInteractable selectionInteractable =  _placedObject.GetComponent<ARSelectionInteractable>();
        if (selectionInteractable is not null)
        {
            // イベントを登録
            selectionInteractable.selectEntered.AddListener(SelectEntered);
            selectionInteractable.selectExited.AddListener(SelectExited);
        }
    }

    private void HoverEntered(HoverEnterEventArgs arg0)
    {
        // インタラクタがインタラクタブルを選択できる状態を開始した時
        // NOP
    }

    private void HoverExited(HoverExitEventArgs arg0)
    {
        // インタラクタがインタラクタブルを選択できる状態を終了した時
        // NOP
    }
    
    private void SelectEntered(SelectEnterEventArgs arg0)
    {
        // インタラクタがインタラクタブルを選択した時
        // NOP
    }

    private void SelectExited(SelectExitEventArgs arg0)
    {
        // インタラクタがインタラクタブルを選択を終了した時
        _placedObject.GetComponent<Rigidbody>().isKinematic = false;
    }

    // Update is called once per frame
    void Update()
    {
        foreach (ARPlane plane in _planeManager.trackables)
        {
            // 検出した平面を非表示にする
            plane.gameObject.SetActive(false);
        }
    }
}

```

## XR Interaction Managerにスクリプトを追加
* Plane Manager
* Placement Iteractable

![スクリーンショット 2023-10-09 23.51.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729904/12fbf490-4f90-0916-2ab3-3d1e660d3aae.png)

# 結果
https://youtube.com/shorts/ZQ8xNliuvv0