UnityのVRアプリサンプルからVisionProアプリの開発を始める(導入編)

# はじめに
普段は業務でもApple Vision Proの開発をしているのですが、最近(2024年8月現在)はあまり個人開発でVR関連の知見が得られていなかっため、基礎的なノウハウをこの機会に学ぶため、基本的なXR関連のフレームワークを触っていました。

その結果として、一定の条件を満たせば、Unityの[PolySpatial](https://docs.unity3d.com/Packages/com.unity.polyspatial.visionos@1.3/manual/index.html)のサンプルベースでなくとも、従来のVRアプリ開発のスタイルに近い方法でVision Proのアプリの開発ができそう、ということがわかりました。

本記事では、従来のVRアプリを開発する際のサンプルに少し変更を加えて、VisionPro実機で動作させる内容をとりあげます。

:::note warn
PolySpatialの利用はUnity Proのライセンスが必要になります。
:::
:::note warn
PolySpatial 1.3.1前後での動作確認のため、将来的にこの記事の方法では動かなくなる可能性があります。
:::

# 前提条件について
本記事はVisionProのImmersive Spaceモードを前提としたアプリ開発を前提としており、WindowやVolumeモードに対応した開発は考慮していません。(Window、Volume、Immersive Spaceについては[WWDC2024の動画](https://developer.apple.com/jp/videos/play/wwdc2024/10153/)を参照)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/e452bd15-a83e-6a2a-5cdc-a820250605f0.png)

また、この記事の方法では `Play To Device` の動作確認はできていません。

# 動作確認したUnityバージョンやパッケージなど
本記事で利用したUnityEditorのバージョンや、プロジェクトで使用したパッケージの内容を以下に記述します。

#### Unityプロジェクトバージョン
- 2022.3.42f1

#### プロジェクトのデフォルトでインストールされるパッケージ(テンプレートはUniversal 3D)
- Core RP Library 14.0.11(com.unity.render-pipelines.core)
- Shader Graph 14.0.11(com.unity.shadergraph)

#### 自分でインストールするパッケージ

- XR Plugin Management (com.unity.xr.management) 4.5.0
- XR Interaction Toolkit (com.unity.xr.interaction.toolkit) 3.0.5 ※今後の記事で利用する予定
- XR Hands (com.unity.xr.hands) 1.4.1
- Apple visionOS XR Plugin (com.unity.xr.visionos) 1.3.1
- PolySpatial (com.unity.polyspatial) 1.3.1 
- PolySpatial XR (com.unity.polyspatial.xr) 1.3.1
- PolySpatial visionOS (com.unity.polyspatial.visionos) 1.3.1

#### 依存関係で自動的にインストールされるパッケージ(開発に関連するパッケージのみ抜粋)

- AR Foundation (com.unity.xr.arfoundation) 5.1.5
- Input System (com.unity.inputsystem) 1.8.1 
- Newtonsoft Json (com.unity.nuget.newtonsoft-json) 3.2.1

# プロジェクトのセットアップ
上記依存するパッケージをインストールした状態から、箇条書きで説明します。

- [Project Settings] > [XR Plug-in Management] > [Plug-in Providers]
    - `Apple visionOS` にチェックを入れる
![スクリーンショット 2024-08-17 3.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/e84ba9ff-442a-54a8-2fd5-817c6a62c552.png)

- [Project Settings] > [XR Plug-in Management] > [Plug-in Providers] > [Apple visionOS]
    - App Modeを `Mixed Reality - Volume or Immersive Space` に変更する
![スクリーンショット 2024-08-17 3.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/bf8d1966-c0e3-0288-c2a1-34f14e6ca734.png)
    - Hands TrackingとWorld SensingのそれぞれのUsage Descriptionに適当な理由を入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/0c7ed794-d018-f6a5-376f-da175d8e8cf3.png)

- Package ManagerからXR Handsのサンプルファイル(GesturesとHandVisualizer)をインポートする
![スクリーンショット 2024-08-17 3.37.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/fe4892f4-dbe8-c3ae-ac76-270afa6da980.png)

# サンプルアプリに必須コンポーネントを追加

- XR Handsのサンプルのシーン `HandGestures` を複製し、別のシーン名(例：`HandGesturesAVP`)で保存して開く
![スクリーンショット 2024-08-17 6.06.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/2e1cc8de-a732-b267-e82c-01a3ba4b4790.png)

- Projectの `Assets/Resouces` フォルダ配下で右クリックメニューから [Create] > [PolySpatial] > [Volume Camera WIndow Configuration] をクリックして追加する
![スクリーンショット 2024-08-17 3.46.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/f763a856-1e47-173b-c990-e8f2467da831.png)

- 追加したVolume Camera Window Configurationを、Inspectorから Mode を `Unbounded` に変更する
(※ `Bounded` ではハンドトラッキングが動作しない)
![スクリーンショット 2024-08-17 3.46.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/62b9e608-00fb-f2fb-562f-1a900619d7f2.png)

- シーンのHierarchy上で右クリックメニューから [XR] > [Setup] > [Volume Camera] をクリックして追加する
![スクリーンショット 2024-08-17 3.41.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/2ffb3abb-47cd-8afb-0539-9bc8a2149463.png)
- VolumeCameraの位置を原点位置(0,0,0)になっているか確認する
    - VolumeCameraの位置が視点の原点位置になるため、ズレると表示がおかしくなる
- 追加したVolume Cameraを、InspectorからVolume Window Configurationに先ほど作成したものを指定する
![スクリーンショット 2024-08-17 3.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/33482d45-a478-2741-846b-04eb36f4f8c9.png)
![スクリーンショット 2024-08-17 3.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/d5fc1e17-f8c1-011a-6584-906fc0bb9ffe.png)

- シーンのHierarchy上から、右クリックメニューから [XR] > [AR Session] をクリックしてXR Originの子のGameObjectとして追加する(ARSessionとARInputManagerのコンポーネントがアタッチされる)
![スクリーンショット 2024-08-17 3.50.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/e4e4b567-b600-948b-4043-41e4a4192225.png)

- ↑と同様に、Hierarchy上から、右クリックメニューから [XR] > [Interaction Manager] をクリックしてXR Originの子のGameObjectとして追加する(XRInteractionManagerのコンポーネントがアタッチされる)
![スクリーンショット 2024-08-17 3.50.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/e59bc970-6ca6-12ce-44a5-b777e0f0fd6f.png)

- XROrigin配下のLeftHand、RightHandのGameObjectに割り当てられている、手のモデルのマテリアルを `Universal Render Pipeline/Lit`　ベースのマテリアルに差し替える
![スクリーンショット 2024-08-17 3.49.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/0d0cb04a-b6ea-6b43-de1f-f0c63266ec1d.png)
- マテリアルはシェーダーが `Universal Render Pipeline/Lit` になっていれば良い
![スクリーンショット 2024-08-17 10.58.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/cca61cab-bc34-9020-9340-a1c54b926cc4.png)

作業後のHierarchyはこんな感じになっていればOK。ビルド前にSceneを保存します。
(後から気づいたのですが、VolumeCameraさえあれば、UI系のGameObjectはVolumeCameraの配下になくても動作します)
![スクリーンショット 2024-08-17 10.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/d365e0f8-b521-dee5-1c0b-e99e21e4ff94.png)

VolumeCameraの配下にあるGameObjectはそれぞれ独立したUIになっています。詳細の情報が欲しい場合はAdvancedPoseDebuggerの方を有効にしても良いかもしれません。
(後に出てくるスクショはAdvancedPoseDebuggerを有効にした場合の画面になります)

# UnityProjectをビルド
iOSアプリと同様に、UnityからXcodeプロジェクトへ出力するためのビルドを行います。

- Shift + Ctrl(Command) + B を押してBuild Settingsのダイアログを表示し、プラットフォームをvisionOSに切り替える
- Scenes in Buildに登録されているSceneをさっき作成したシーンに差し替える
- Buildをクリックする
![スクリーンショット 2024-08-17 3.51.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/57c393cf-6bae-c513-a4c6-a7413c375df2.png)
- ビルド時に出力先のディレクトリを選択するダイアログが出てくるので、Projectフォルダ直下に適当なフォルダ(例: `Builds`)を作り、そのフォルダを選択してビルドする
![スクリーンショット 2024-08-17 10.41.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/f2b93100-98f3-475b-3faf-841c576b0649.png)

今度はXCodeでアプリをビルドし、VisionProにアプリを転送します。
(事前に必要なXcode周りの設定は省略します)

- 出力されたファイル内にXCodeプロジェクトファイル(Unity-VisionOS.xcodeproj)が生成されているので、ダブルクリックで開く
![スクリーンショット 2024-08-17 10.43.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/902d418a-b691-d7a2-83a1-9824332e5e84.png)

- [Signing & Capabilities] > [Signing] のメニュー下で `Automatically manage signing` にチェックを入れ、 `Team` をApple Developer Programが有効になっているものを指定し、ビルドを実行
![スクリーンショット 2024-08-17 3.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/46df2fb2-1403-4cfd-bd6d-dd20c208c9e4.png)

# アプリを実行した際の実機画面

このように、XR HandsのサンプルアプリがVision Proでも動いています。

![IMG_0066.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58376/5994e69b-a147-db31-7a90-46b1b7cd013e.png)

# 終わりに

Vision Proのアプリ開発といえば、PolySpatialのサンプルアプリベースのものを使って紹介していることが多いのですが、Immersive Spaceに限定してしまえば、従来のVR開発ともシナジーがありそうです。
今後もこの方法が使えるのであれば、他のVR HMDとのクロスプラットフォーム開発も視野に入りそうです。
また、XR Interaction ToolkitベースでのサンプルアプリもVision Proで動作したので、そちらも近いうちに記事にしようと思います。