Needle EngineでマルチプレイヤーWebXRアプリをVercelにセルフホストする

# はじめに

**Needle Engine**は、ブラウザ上で高度な3Dコンテンツを動作させるためのWebベースの3Dエンジンです。UnityやBlenderといった既存の3D制作ツールと統合でき、インタラクティブな3Dシーンを容易に導入することを目的としています。Web標準技術上に構築されており、**WebGL**対応のブラウザ環境であればデスクトップからモバイル、VR/ARデバイスまで幅広く動作します。

用途としては、Webブラウザ上で動作するゲームやインタラクティブなプロモーションサイト、製品の3Dビューア、教育・トレーニング用のVRコンテンツ、ARを用いたデモンストレーションなど多岐にわたります。にマルチユーザ対応やWebXR対応も備えているため、リアルタイム共同作業やデジタルツインといった応用にも適しています。


このNeedle Engineで作ったシーンはNeedle Cloudにアップロードして公開することも可能ですが、自分のサイトにホスティングすることも出来ます。この記事では、Needle Engineの概要と、シーンの準備からVercelでの公開までの流れをまとめます。

## Needle Engineの概要

Needle Engineはブラウザで動作する**フル機能の3Dエンジン**です ([Feature Overview | Needle Engine Documentation](https://engine.needle.tools/docs/features-overview.html#:~:text=Needle%20Engine%20is%20a%20fully,and%20our%20Samples%20and%20Showcase))。Webページ上でリッチな3D体験を提供でき、従来のWeb開発ワークフロー（HTML/CSS/JavaScript）に3Dコンテンツを組み込むことができます。たとえば、Needle Engineを使えば3DシーンとレスポンシブなHTMLインターフェースをシームレスに統合でき、ReactなどのフロントエンドフレームワークやプレーンなHTML/CSSとも併用可能です。これにより、Webサイト内に埋め込まれた3Dモデルの操作や、スクロール連動の3Dアニメーションなど、**インタラクティブなWebコンテンツ**を容易に作成できます。

Needle Engineは初めから**XR（AR/VR）**用途を念頭に設計されており、WebXRデバイスAPIを通じてVRヘッドセットやAR対応ブラウザでの表示に対応しています。スマートフォンのブラウザ上でカメラを使ったAR表示や、VRヘッドマウントディスプレイでの没入型体験を単一のコードベースで提供できます。

## Needle Engine+Unityでの開発

開発者はUnity上でオブジェクトにスクリプト（コンポーネント）をアタッチし、シーンを構築していきます。Needle Engineのスクリプトは**TypeScript/JavaScript**で記述し、Unityエディタ上では対応するダミーのC#コンポーネントとして扱われます。TypeScriptで記述されたコンポーネントはエクスポート時にそのままWebで動作し、エンジンが用意するコンポーネントシステム上で実行されます。開発時には**ホットリロード**や**Editor Sync**（Unityエディタの編集内容を即座にブラウザに同期する機能）を備えており、Unity上でシーンを編集するとほぼリアルタイム（1秒以内程度）にブラウザ上の表示へ反映されます。

### VercelにSandboxシーンをホスティングする。

それではここからは、Needleが提供するSandboxシーンを自分のサイトに公開する流れを説明します。Needle EngineにはGlitch, itch.io, GitHub Pagesなどに公開するためのコンポーネントもありますが、今回はより高速で多機能な[Vercel](https://vercel.com/)に公開するための手順をまとめます。

#### 準備
Vercelのアカウントは無料で作れるので、以下の作業を始める前に作っておいてください。

Unityエディタのバージョンは **Unity 2021.3 LTS または 2022.3 LTS, Unity 6** です

また、Needle Engineを利用するには**Node.js**環境が必要です。Needle Engine推奨のバージョンは Node.js 20 LTS または 22 LTS です。インストール方法については[こちらの記事](https://qiita.com/nayoshik/items/c0febffab4a4b0ffb3b9)を参考にしてください。



## 2. Needle Engineのセットアップ
次に、UnityプロジェクトにNeedle Engineを導入し、サンドボックスシーンを開きます。

レンダーパイプラインはUniversal Render Pipeline (URP) and Built-In Render Pipeline (BiRP)に対応しています。新規作成時には"Universal 3D"か"3D (Built-In Render Pipeline)"のテンプレートを選んで下さい。 

**Needle Engineパッケージのインストール**: [Needle Engine公式サイト](https://engine.needle.tools/docs/getting-started/)からUnity用の `.unitypackage` ファイルをダウンロードし、既存のUnityプロジェクトにインポートします。ダウンロードしたファイルをダブルクリックするか、Unityエディタのプロジェクトウィンドウにドラッグ＆ドロップしてインポートしてください。

インポートを実行すると、自動的に必要なファイルが追加されます 。インポート完了後、**「A new scoped registry...」**といった通知ウィンドウが表示された場合は、Needle Engineのパッケージ登録に関するものなので"Close"で閉じて問題ありません。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/393a8cc5-ff8f-6068-1f47-5abdcfbb1cb9.png)

インポート終了時にはもう一つ、Welcomeメッセージが出ます。ここでCreate New Scene With Templateを選んで、シーンを保存してください。
<img alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/2e030797-e4d7-9814-4385-bbbdb919335f.png" width="45%">

すると、Sandboxシーンが表示されます（Welcomeで選ばなかった場合は、File/New Sceneでテンプレートを選ぶことも出来ます）。Hierarchyの中に、最初からNetworkingやXRが入っていることに注目しましょう。つまり、この時点でマルチプレイヤーやXR対応のためのコンポーネントが含まれているということです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/3c791e58-cca4-df4c-e84c-10a4ac1ee159.png)

**Needle Engine Projectの設定**: HierarchyのExportを選んで、InspectorにあるNeedle Engine (Project & Export)を御覧ください。

<img alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/baa22fb2-81c1-05e3-c404-90a9949ebd48.png" width="90%">

基本的には、このままで問題ありませんが、必要に応じてProject Folderの保存場所を選択してください。また、TemplateはデフォルトのViteを選ぶのが一番無難なので、Needleに十分慣れるまではこのままにしてください。

次にProject Validationですが、Open Validation Windowを選んで指示に従ってください。おそらく"Needle Engine EULA needs to be accepted before you can start using Needle Engine."に警告が出ていると思うので、その横にある"Open EULA Window"をクリックし、画面が出てきたらチェックボックスをすべてチェックし、I agree to EULAのボタンを押してください。

そのあとに、Generate Projectを押すと、右下のステータスバーが忙しく動き、Nodeモジュールのインストールなどの処理が行われて、プロジェクトが生成されます。つぎにそのまま、プロジェクトがローカルマシン上にデプロイされてブラウザが開き、Sandboxシーンが表示されるはずです。

もしブラウザが開かないときは、少なくともTerminalが開いて以下の図のようになっていることを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/31953da6-cc51-57b8-27d7-8bab757d092f.png)

ご覧の通り、Needle EngineがVITEでローカルホストを立ち上げています。*https://localhost:3000* とあるので、これをブラウザで開いてください。Your connection is not privateという感じの警告が出ると思いますが、Advancedなどのボタンを押すとでてくるProceed to localhostなどのボタン（ブラウザにより違う）をクリックして開いてください。Sandboxシーンを見ることができるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/9c336ca4-55d9-aa6e-54f4-f6e9bba52d53.png)

さて、Unityに戻って再びExportのInspectorをみると、Needle Editor Syncのところに"@needle-tools/editor-sync package is not installed - click the button below to add it to your web project"と警告が出ているかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/cbc777ed-cdf1-71ad-0566-2e76ce4692f8.png)

出ていたら、Install Editor Sync Packageをクリックしてインストールしてください。Terminalをみると、自動的にインストールされてVITEサーバーが再起動する様子を確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/108e5a39-8b66-83a5-edf0-93e9a5daf9f5.png)

Editor Syncは実験的機能でChromeのみで動作するようですが、UnityのSceneウィンドウで行った修正が(Sceneファイルを保存しなくても)ブラウザ上のシーンに反映されるので便利です。

## 4. Vercelにデプロイ

次に、プロジェクトを**Vercel**上にデプロイします。通常であれば、プロジェクトをGithubのレポジトリにPushして、Vercel上でビルドとデプロイを行うのですが、Needle Engineの場合、デフォルト状態だとローカルの依存ファイルがGithub上にアップロードされないので失敗します。そのため、以下の手順が必要です。


まず、ルートディレクトリにTerminalで移動してください。そこで、以下の命令を順番に実行してください。最後の```npx vite --host```で、上で行ったのと同じように、https://localhost:3000 でシーンを開けるはずです。

```
nvm use stable
npm install vite
npx vite --host
```
```nvm use stable```が上手く行かないときは
```
nvm install 22
nvm use 22
```
を代わりに実行してください。

ここから、Vercelへのデプロイを行います。

**Vercelのアカウント作成**: まだアカウントがない場合は、Vercel公式サイトで無料アカウントを作成します。GitHubやGoogleアカウントでサインアップできるので、それらを利用すると簡単です。

**Vercel CLIのインストール**: ローカル環境からデプロイするため、Vercel CLIをインストールします。Node.jsがインストール済みであれば、ターミナル/コマンドプロンプトで次のコマンドを実行してCLIを導入できます。
```
npm install -g vercel   # Vercel CLIをグローバルインストール
```

- **CLIでのログインとプロジェクト設定**: Vercel CLIを導入したら、まずターミナル上で`vercel login`コマンドを実行し、CLIからVercelアカウントにログインします。
```
vercel login
```

次に、プロジェクトをデプロイするため`vercel`コマンドを実行します。初回実行時には対話式のプロンプトが表示されるので、以下の点を設定します。
  **1)** Set up and deploy.. はyes
  **2)** Which scope should contain your project?は、そのままEnter
  **3)** Link to existing project? は **`N`**（No）を入力します （今回は新規プロジェクトとしてデプロイするため）。  
  **5)** 「Which directory is your code located in? (プロジェクトのコードはどのディレクトリにありますか)」はデフォルト（"./"、つまりカレントディレクトリ）でOKです。
すると、設定ファイルを自動的に見つけ、以下のようなメッセージが出ます。
```
Local settings detected in vercel.json:
Auto-detected Project Settings (Vite):
- Build Command: vite build
- Development Command: vite --port $PORT
- Install Command: `yarn install`, `pnpm install`, `npm install`, or `bun install`
- Output Directory: dist
```
UnityでNeedle Engineの設定をするときにTemplateとしてViteを選んでいるので、ここでProject Settingとして自動検知されます。この次に Want to modify these settings? 聞いてきますが、このままでよいので noを選んでください。デプロイが開始されます。
```
🔗  Linked to ***projects/*** (created .vercel and added it to .gitignore)
🔍  Inspect: https://vercel.com/***projects/***/*** [4s]
✅  Production: https://***-projects.vercel.app [4s]
📝  Deployed to production. Run `vercel --prod` to overwrite later (https://vercel.link/2F).
```
という感じのメッセージが出てくれば完了です。Productionのところにでているリンクをブラウザで開けば、デプロイされたプロジェクトを視ることができるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/29d97d66-ccad-6650-4692-9b8674384e6b.png)

ページのURLにroom=....という番号がついていることに注目してください。この番号付きのURLを共有することで、簡単に複数プレイヤーで空間を共有することが出来ます。ただし、Vercelプロジェクトのデフォルト設定では自分のVercelアカウントでログインしていないデバイスではページを見れないので、ログインするか、プロジェクトのSettingsのDeployment ProtectionにあるVercel AuthenticationのEnabled forのトグルをオフにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/b37826b4-8a94-d046-26e1-c62e963fc3b0.png)

Open on Questとあるように、VRにも対応しています。

これからプロジェクトを修正したときは、vercel --prodでデプロイを追加出来ます。

```
vercel --prod
```

この時、デプロイする毎にProductionのURLは変化することに注意してください。もし、変化しないURLを使いたい場合は、
```
vercel inspect **あなたのProduction URL**
```
で情報を取得します。すると以下のような情報が出てきます
```
  General

    id		dpl_B+**************3
    name	u+*******3
    target	production
    status	● Ready
    url		https://*****-projects.vercel.app
    created	Tue Feb 11 2025 23:29:24 GMT+0900 (Japan Standard Time) [7m ago]


  Aliases

    ╶ https://******3.vercel.app
    ╶ https://*******3-*****projects.vercel.app
    ╶ https://*****3-*****-projects.vercel.app
```    
この中でAliasesの一番上のもの（ランダムな文字列が含まれないもの）は最も最近のデプロイを常に指し、不変です。他の人とページを共有するときには、これを使うとよいでしょう。

# 最後に

ブラウザ向けの軽量なVRアプリを作れるのは大きな利点です。UnityやUnreal Engineなどとは作業の流れが違うため戸惑いますが、今回の記事が参考になれば幸いです。