UnityとReality Composer Proで比較！Apple Vision Proアプリ開発のポイント

# はじめに

私のチームでは今年 Apple から発売された空間コンピューティングデバイスの Apple Vision Pro を購入し、デモアプリを作っています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/4035ff80-e93b-f8fe-cc59-49988d21b6e8.png" width="600">

Apple Vision Pro は現在 Swift、Unity、Unreal Engine、Web などで開発ができます。

私は Unity に慣れているため、最初は Unity で開発をしていましたが、「[Apple Vision Pro アプリ開発ガイド〜visionOS ではじめる空間コンピューティング実践集](https://gihyo.jp/book/2024/978-4-297-14311-4)」という本（以後参考本）を読み、Xcode 内にある [Reality Composer Pro](https://developer.apple.com/jp/augmented-reality/tools/) というUnityのような見た目のツールを使えば、簡単なものなら Swift のコードをほとんど書かずに作れるということが分かりました。

![スクリーンショット 2024-12-12 10.05.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/d311b4c4-7325-0c6d-b3ca-8ff008f9c7ef.png "キャプションテキスト")


そこで今回は Unity と Reality Composer Pro で同じようなものを作ってみて、開発のポイントを比較しました。

比較項目と結果の概要は以下の表のとおりです。それぞれの項目についての詳細は後述します。

| 比較項目         | Unity                             | Reality Composer Pro                        |
| ---------------- | --------------------------------- | ------------------------------------------- |
| **ライセンス**     | [有償ライセンス](https://unity.com/ja/products/compare-plans)が必要    | 不要（Xcodeに付随）          |
| **アセット**     | Unity Asset Store の利用が可能    | 内蔵アセットまたは usdz 形式が必要          |
| **パーティクル** | Editor と実機での見た目に差がある | 見た目の差はなし。プリセットあり        |
| **手の実装**     | XRHandSubsystem で高度な制御可能  | Anchoring で追随だけなら手軽に実装可能                  |
| **AI サポート**  | GitHub Copilot の利用が可能       | Xcode 内で Swift Assist が今後利用可能?     |
| **実機確認**     | Play to Device で迅速に確認可能   | インタラクティブなものは Xcode ビルドが必要 |

# (Unity ユーザ目線の)メリットデメリット

## Unity

### メリット

- アセットの種類が豊富
- Unity に慣れている場合、効率的に開発が可能

### デメリット

- 有償ライセンスが必要（Pro ライセンス以上）
- パーティクルやマテリアルなど実機と Editor で見た目の違いが多い

## Reality Composer Pro

### メリット

- Apple Vision Pro 専用に最適化されている
- 内蔵の高品質アセットが利用可能

### デメリット

- 細かい制御が必要な場合、Swift のコードを書く必要がある

# 対象
本記事は、以下のような方々を対象としています
- Apple Vision Proの開発に興味があり、UnityとSwiftの選択で迷っている開発者
- Unityの経験があり、Swiftでの開発にも挑戦してみたい方

# 作ったもの

ランプをさわると、パーティクルとともに猫魔人が現れます。

### Unity

ピンチ動作でランプを持てます。どちらかの手を近づけると反応して猫魔人が現れます。

![UnityLamp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/8fe18276-6da6-2443-7724-78efbed06984.gif)

### Reality Composer Pro

ランプは最初から左手にくっついています。右手をランプに触れると猫魔人が現れ、しばらくすると消えます。

![RCPLamp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/166c3d6c-70d9-38bd-2660-e0fa65b5abb8.gif)

# 開発環境

- Apple M1 Pro
- Vision OS：2.1
- Xcode：16.1
- Unity：6000.0.22（Pro ライセンス以上が必要です）
- PolySpatial：2.0.4
- RealityComposerPro：2.0

# 比較

## ベースシーン

### Unity
UnityでVision Proの3Dアプリケーション開発を行うには[PolySpatial](https://docs.unity3d.com/Packages/com.unity.polyspatial.visionos@0.1/manual/index.html)というアセットが必要です。

オブジェクトをつかむ「Manipulation」というサンプルがあるので、これをベースとしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/2ab898d0-cc78-57d6-72c1-9f9904dc7d59.png" width="600">

他にも機能に応じてシンプルなサンプルシーンがあるので、用途に応じてサンプルシーンを改変して作成していきましょう。

### RealityComposerPro
Xcode&SwiftのVisionOSで使えるサンプルプロジェクトもApple公式から50個以上提供されています。
公式のサンプルプロジェクトの種類については以下の記事が参考になります。

https://zenn.dev/satoshi0212/articles/da9b47a42586f4

ただ、今回の用途に合っているRealityComposerProを使ったシンプルなサンプルがあるか把握できていないため、Xcodeのデフォルトのシーンをベースとしました。
Xcode で Window 形式でプロジェクトを作り、Packages フォルダの下の Package.realitycomposerpro を RealityComposerPro で開いて、球体のシーンを置き換えていきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/48fc5af2-acc3-21bd-49cf-12f270b31b38.png" width="600">



## アセット

### Unity

Unity には[Unity Asset Store](https://assetstore.unity.com/ja-JP)というアセットストアがあり、無料有料を含めたくさんの 3D モデルなどのアセットがあります。これが Unity の強みですね！

ただし今回は Unity と Swift で共通化するために生成 AI で作成した 3D モデルを使います。  
Unity 向けには FBX で書き出して読み込みました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/f7120b53-c51e-c959-4c62-af4f46cce00f.png" width="300">

余談ですが、Swift などでよく使われる usdz 形式や Web でよく使われる glb 形式は Unity はデフォルトではサポートしていません。 普段 Web でも XR 開発をしている身としては、Web は glb、Swift は usdz、Unity は fbx・・・と様々な形式を使うことになり、やや面倒です。

### RealityComposerPro

今回は生成 AI で生成したものを使いますが、RealityComposerPro 内にも高品質な 3D モデルがいくつか用意されています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/ee8fc933-2dfb-fc0f-1b65-a2ac0088be24.png" width="600">

外部から 3D モデルを import する場合は usdz 形式である必要があります。  
[Reality Converter](https://developer.apple.com/jp/news/?id=01132020a)という Apple が出しているツールを使って、obj や gltf などの形式のモデルを usdz 形式に変換できます。

## パーティクル

### Unity

Unity でのパーティクルは Unity Editor 上での見た目と、実機で実行した時の見た目がかなり異なるので扱いが大変です。またシェーダーも限られており、UnityAssetStore にあるパーティクルをそのまま使えることが少なそうです。
そのため今回は、PolySpatial のサンプルの中にあった炎のパーティクルのテクスチャを白黒にして煙っぽくしてみました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/18b6105e-991d-8e66-f48a-4795bec3357b.png" width="600">

### RealityComposerPro

ParticleEmitter でパーティクルを作れます。設定内容は Unity と似ています。  
プリセットとして 6 種類のパーティクルがあり、今回はこの中の Impact という煙のようなものを使いました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/4481fda0-bdcb-6a2b-7d39-3dcfd345d49e.png" width="600">

## 手の判定

### Unity

手の接触判定は Unity の[XRHandSubsystem](https://docs.unity3d.com/Packages/com.unity.xr.hands@1.1/api/UnityEngine.XR.Hands.XRHandSubsystem.html)を使い、人差し指の位置を取得し、ランプとの距離で判定を行いました。

![スクリーンショット 2024-12-11 17.42.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/c5c0bd95-a269-76cb-3720-4412e5655ba5.png)

以下の記事を参考にしました。

> PolySpatial で Vision Pro アプリを作ってみよう(応用編)  
> https://gaprot.jp/2024/04/08/polyspatial-vision-pro-application/


### RealityComposerPro

Component の中にある Anchoring を使えば指定した指や手に物を追従させることができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/6dda9ec0-3f4b-1579-094a-739699ce289d.png" width="400">

ただし Anchoring コンポーネントを使うとコライダー判定などの物理シュミレーションがうまくいかないようなので、今回は[参考本](https://gihyo.jp/book/2024/978-4-297-14311-4)に載っている ARkit を用いたハンドトラッキングコンポーネントを使わせていただきました。

![スクリーンショット 2024-12-11 15.30.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/110887bb-d9c0-bca2-c749-d2f25043a308.png)
これをランプオブジェクトと、右手用の Transform オブジェクトにつけます。また Collision コンポーネントもつけておきます。

そして接触判定は Behaviors というコンポーネントを使いました。これでランプと右手人差し指のコライダーが接触した時に、魔人の出現アニメーションなどを設定した Timeline を流すことができました。

![スクリーンショット 2024-12-11 15.35.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/93da2a8d-6eb5-ab34-7418-70f59a08a07a.png)

ちなみに Timeline は参考本にも載っていなかったため、なんとなくで使ってみましたが、オブジェクトの表示・非表示、透明度変更、移動、Billboard、強調表示アニメーションなどが設定できます。

![スクリーンショット 2024-12-11 16.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/c0586dec-80ca-cd49-7581-9437c7bf7770.png)

## コード生成 AI

### Unity

Unity は VSCode などで開発できるためコード生成 AI ツールの GitHub Copilot を思う存分使って開発できました。
魔人がランプから出てくるアニメーションなどの動きも含め、全体の流れをほぼ自分ではコードを書くことなく実装できました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/5de1e05a-67bd-524a-2eaa-f29772670740.png" width="600">

### RealityComposerPro

今回は書いていませんが、RealityComposerPro 用のコンポーネントなどのコードを書く場合、基本的に Xcode で Swift 言語を使います。
Github Copilot には[Xcode 用の GitHub Copilot 拡張機能](https://docs.github.com/ja/copilot/using-github-copilot/getting-code-suggestions-in-your-ide-with-github-copilot)がありますが、私がよく使っている Copilot Chat や Edits などの機能はまだ使えないようです。
今後 Apple から[Swift Assist](https://www.apple.com/jp/newsroom/2024/06/apple-empowers-developers-and-fuels-innovation-with-new-tools-and-resources/)という機能が出るようなので、これが使えるようになると RealityComposerPro や Swift での開発が少し楽になりそうなので楽しみです！

> Swift Assist は Xcode にシームレスに統合されており、最新のソフトウェア開発キット（SDK）と Swift 言語の機能を把握しているため、デベロッパはプロジェクトと完全に一体化する最新のコード機能を常に使用できます。Swift Assist を使うと、新しいフレームワークを探求したり、新しいアイデアを試すといったタスクも 1 つのリクエストで簡単にできます。
> [Apple、新しいツールとリソースでデベロッパに力を与えイノベーションを推進](https://www.apple.com/jp/newsroom/2024/06/apple-empowers-developers-and-fuels-innovation-with-new-tools-and-resources/)より

## 実機確認機能

### Unity

「[Play to Device](https://discussions.unity.com/t/play-to-device/309359)」という Unity の機能を使うと、Xcode でビルドせず、Unity から直接実機で確認することができます。

![スクリーンショット 2024-12-11 17.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/29ccf52d-6475-b14a-1f3a-947738e22bad.png)

この機能、1 度目はつながっても 2 度目以降つながらないことが多く使っていなかったのですが、Apple Vision Pro をかぶり直す度に Vision OS 側の Play to Device のアプリを再起動すればいいことを最近知りました。アプリ再起動は手間ですが、毎回 Xcode ビルドするよりは断然楽ですね！

### RealityComposerPro

右上のマークから直接実機へ転送することができます。

![スクリーンショット 2024-12-11 16.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190043/d5eeadf7-ec7e-1b76-b690-fdf4d33fd500.png)

ただし、Quick Look としてオブジェクトが見えるのみで、今回のような手への追従などは動きませんでした。
そのためインタラクティブなものを RealityComposerPro で作った場合は、Xcode でビルドする必要がありそうです。



# 最後に

Anchoring や Timeline 機能などにより RealityComposerPro 単体でも動きのあるものやインタラクティブなものがローコードで作れました。使い方自体は Unity に慣れていればある程度分かりそうです。今回は触れていませんが ShaderGraph なども使えます。
シンプルなアプリでしたら、Unity ではなく RealityCpmposerPro を使ってみてもいいかもしれません！