Amazon Web Services ブログ

OpenXRに対応したUnreal Engine VR ServerのAWS上への構築方法

このブログは 「Building an OpenXR Enabled Unreal Engine VR Server on AWS」を翻訳したものです。

BUILD、DELIVER、MANAGE ブログシリーズ : BUILD

拡張現実 (AR)、仮想現実 (VR)、複合現実 (MR) は爆発的な成長を遂げています。拡張現実(XR)と呼ばれる拡張現実(XR)と呼ばれるARとVRは、コンシューマーと開発者の両方から関心を集めています。Omdiaのレポートによると、コンシューマーがVRコンテンツに費やす金額は2026年までに75億ドルに達すると推定されています。スタンドアロン型のVRヘッドセットであるMeta Questの登場により、仮想世界はかつてないほどアクセスしやすく、手頃な価格になりました。 AWS の使命は、空間体験を構築、管理、デプロイできる世界最高の場所になることです。この記事では、OpenXR 対応の Unreal Engine VR Server をアマゾンウェブサービス (AWS) 上ににデプロイし、Meta Quest 2 経由で接続する方法に焦点を当てています。

OpenXR とは

OpenXRは、XRに関連するオープンスタンダードの作成を専門とする非営利コンソーシアムである The Khronos Group がリリースした、XRプラットフォームとデバイスへの高性能アクセスのためのロイヤリティフリーのオープンな規格です。OpenXRを使用すると、開発者は Oculus VRWindows Mixed RealitySteamVR などの一般的な XR プラットフォームでアプリケーションを構築できます。デバイスごとに要件が異なっていたため、開発者はこれまでクロスプラットフォームXRアプリケーションの構築に課題に直面していました。XR デバイスのアクセシビリティと価格が手軽になったことで、Unreal Engine や Unity などの人気のゲームエンジンが OpenXR のサポートを追加しました。

Unreal Engine とは

Unreal Engine は Epic Games が開発した 3D コンピューターグラフィックスのゲームエンジンで、ゲームやエンターテイメント業界で広く使用されています。FortnitePlayerUnknown’s BattlegroundsRocket Leagueなどの成功したゲームは、Unreal Engine で構築されました。バージョン 4.27 以降、Unreal Engine は Oculus VR、SteamVR、Apple ARKit などのプラットフォームでの XR 開発をサポートするだけでなく、クロスプラットフォームの XR アプリケーション開発向けに本番環境対応の OpenXR も提供しています。

ソリューション概要

この記事では、Unreal Engine 5 で VR プロジェクトを設定し、サーバービルドを作成し、Amazon Elastic Compute Cloud (EC2) にサーバーをデプロイし、Meta Quest 2 または別の OpenXR プラットフォームに接続する手順について説明します。

デモアーキテクチャ

image.png

ウォークスルー

このセクションでは、ソリューションを構築してデプロイする方法を示します。

前提条件

Part 1 : AWS でのセットアップ

Unreal Engine サーバーを実行する EC2 インスタンスをセットアップします。

  1. AWS コンソールで EC2 コンソールに移動します。
  2. EC2 コンソールのダッシュボードのインスタンスの起動ボックスでインスタンスの起動を選択し、表示されるオプションからインスタンスの起動を選択します。
  3. 名前とタグ名前に、vr-demo-server などのインスタンスのわかりやすい名前を入力します。
  4. アプリケーションおよび OS イメージ (Amazon Machine Image)で、次の操作を行います。
    1. Quick Startを選択し、次にAmazon Linuxを選択します。これはインスタンスのオペレーティングシステム (OS) です。
    2. Amazon Machine Image (AMI) から、Amazon Linux 2 の HVM バージョンを選択します
  5. インスタンスタイプインスタンスタイプリストから、サーバービルドを実行するのに十分なコンピュートリソースを割り当てるには、少なくとも c5.xlarge を選択します。
  6. キーペア (ログイン)キーペア名で、新しいキーペアを作成してダウンロードするか、アクセス可能な既存のキーペアを選択します。ログインしてサーバーを設定するには、これが必要です。
image.png
  1. ネットワーク設定の横にある編集を選択します。
    1. VPC の場合は、デフォルトの VPC を使用できます。パブリック・サブネットを選択し、パブリック・インターネット経由でインスタンスに接続できるように、パブリック・サブネットを選択し、パブリック・IPの自動割り当てを有効にします。自動割り当てられたパブリック IP を使用して、後でインスタンスに接続します。
    2. セキュリティグループ名には、ウィザードによって自動的にセキュリティグループが作成され、選択されたことがわかります。SSH アクセスと Unreal Engine 専用サーバー (デフォルトでは UDP 経由のポート 7777) を許可するようにインバウンドセキュリティグループのルールを変更します。
image.png
  1. ストレージの設定で、サーバービルドに十分な容量 (100 GB 以上を推奨) があるボリュームサイズを選択します。
  2. Launch Instanceをクリックし、インスタンスのパブリック IP アドレスをメモしておきます。
    1. AWS コンソールで EC2 コンソールに移動します。
    2. 左側のメニューバーから、インスタンスをクリックします。
    3. vr-demo-server を見つけて選択します。
    4. インスタンスの詳細タブで、パブリック IPv4 アドレスを探し、後で使用できるようにメモします。

Part 2 : OpenXR を使ったUnreal Engine 5 プロジェクトのセットアップ

Unreal Engine には、プロジェクトのボイラープレートを含む VR テンプレートが用意されています。OpenXR プラグインのほか、ヘッドマウントディスプレイ (HMD) とコントローラーのロジックとメッシュも含まれているため、多くの一般的な VR ヘッドセットをプロジェクトに簡単に統合できます。サポートされているデバイスは、VR テンプレートの Unreal ドキュメントに記載されています。

  1. VR デモの作成を開始するには、Game カテゴリの Virtual Reality テンプレートを使用して新しい Unreal Engine プロジェクトを作成します。プロジェクト名を選択します。この記事では vrdemoを使用します。<projectname> というプロジェクト名はあとで参照されます。
image.png
  1. このテンプレートは Blueprintとして提供されていますが、サーバービルドを作成するには、それを C++ プロジェクトに変換する必要があります。そのためには、空の C++ クラスを作成します。上部のメニューバーで、ToolsNew C++ Classを選択します。
    1. 親クラスとしてNoneを選択します。
    2. 新しい C++ クラスの名前を入力し、Createを選択します。
  2. テンプレートには、作成済みのマップが付属しています。これはサーバーのデフォルトマップとして使用され、それを複製してオフラインマップを作成します。これにより、ローカルマップとオンラインマップを区別できます。コンテンツブラウザで、VRTemplate/Maps フォルダに移動します。

    1. VRTemplateMap を右クリックし、Duplicateを選択します。
    2. コピーしたものの名前を OfflineMap に変更します。
    3. メニューバーで BuildBuild All Levelsを選択して、新しいマップ用の照明が構築されていることを確認します。
    4. メニューバーで SaveSave Allを選択します。
  3. 次に、プロジェクト設定を変更してデフォルトマップを設定し、パッケージ設定を更新します。このプロジェクトから 2 つのパッケージを作成します。サーバービルドは Linux で実行され、クライアントは Android を実行する Quest 2 上で実行されます。別のヘッドセットを使用している場合は、ターゲットプラットフォームに応じてパッケージ設定を変更する必要がある場合があります。メニューバーで、EditProject Settingsを選択します。
    1. Project Settings の Project カテゴリで、Map& Modesを選択します。
      1. Default Mapセクションで、Advanced Settings を展開します。
      2. Game Default MapOffline Map に変更します。
      3. Server Default MapVRTemplateMap に変更します。
    2. Project Settings の Projectカテゴリで、Packaging を選択します。
      1. Advanced Settings を展開します。
      2. List of maps to include in a packaged build に、2 つの配列要素を追加します。
      3. パスについては、VRTemplate/Maps を参照し、OfflineMapVRTemplateMap を選択します。


image.png

    1. Project Settings の Projectカテゴリで、Supported Platform を選択します。
      1. Android Linuxを選択します。
    2. Project Settings の Engineカテゴリで、Navigation System を選択します。
      1. Allow Client Side Navigationを選択します。
    3. Project Settings の Platformカテゴリで、Android を選択します。
      1. Minimum SDK VersionTarget SDK Version に、ヘッドセットに必要な API レベルを入力します。本ブログ執筆時点で、アップデートされた Quest 2 は Android API レベル29 です。
      2. ここに緑色のバナーが表示されない場合は、Configure Now を選択し、Accept SDK License を選択します。
      3. Project SDK Override セクションで、ヘッドセットのSDK API Level を入力します (例: android-29)。

<Tip> 別な方法として、Android SDK 設定でこれを更新してすべてのプロジェクトに設定することもできます。
<Note> 本記事の執筆時点では、プロジェクトは Platform SDK 33 のソースファイルから削除された依存関係を使用するため、ここでオーバーライドしないとビルドエラーが表示されることがありました。

image.png

Part 3 : ウィジェット メニュー

Part 2 のマップ構成では、作成したばかりのオフラインマップにユーザーが生成されます。オンラインサーバーマップに接続するには、VR のインターフェースが必要です。これを実装するには、次に、Part 1 で作成した VR デモサーバーに接続するオプションを追加して、VR テンプレートのデフォルトウィジェットメニューを拡張します。

  1. コンテンツブラウザで VRTemplate/Blueprintsに移動し、WidgetMenu を開きます。
  2. Hierarchy パネルで既存のボタンを選択してメニューオプションを複製し、それをコピーしてVertical Box コンポーネントの下に貼り付けます。
  3. ボタンの名前を ConnectButton
    に変更し、テキストをConnectに変更します。
image.png
  1. Graph ビューで、新しいボタンを選択して On Clicked イベントを作成します。
  2. On Clicked イベントから、Open Level ノードをアタッチします。
  3. Level Name には、EC2 のパブリック IPv4 アドレスを入力します。
  4. 再起動ボタンの Open Level ノードを探し、Level Name を前に作成した OfflineMap に変更します。
  5. これで、WidgetMenu ウィンドウをSaveCompile、および閉じることができます。
image.png

この新しい Connect ボタンをクリックすると、クライアントはポート 7777 の UDP 経由でサーバー IP アドレスへの接続を試みます。接続に成功すると、ユーザーはサーバー上で実行されている VRTemplateMap に生成されます。Restart ボタンをクリックすると、ユーザーは現在サーバーマップに指定されている VRTemplateMap ではなく、OfflineMapに移動します。

Part 4 : VR Pawn

複数のユーザーがサーバーに接続できるようになりましたが、お互いには見えません。ユーザーはVRでつながっているため、ヘッドセットとコントローラーのモデルを見て、3D空間で個別に追跡したいと思うでしょう。そのためには、VR
テンプレートで提供されるスタティックメッシュを使用し、変数を複製してそれぞれのトランスフォームを追跡できます。

  1. コンテンツブラウザの右上の Settings を展開し、Show Engine ContentShow Plugin Content を選択します。
  2. コンテンツブラウザで VRTemplate/Blueprints に移動し、VRPawnを開きます。
  3. VRPawn ブループリント内で、LHandTransformRHandTransform、および HeadTransform という名前の 3 つの新しい変数を作成します。これらの変数は、コントローラーと HMD の位置を追跡するために、マップ内のユーザーごとにインスタンス化されます。
    1. Variable TypeTransform を選択します。
    2. ReplicationReplicated を選択します。
    3. Replication Condition で、Skip Owner を選択します。
image.png

image.png
  1. イベントグラフで、右クリックして Custom EventSetTransformROSという名前を付けます。この機能は、サーバー上のユーザーのHMDとモーションコントローラーの位置と回転を変更します。Unreal Engine のマルチプレイヤーフレームワークは、各ユーザーの位置をサーバーから他のクライアントに複製します。
    1. Replicate では、Run on Server を選択し、Reliable を選択します。
    2. 作成した変換変数に 3 つの変換入力を追加します。
    3. イベントグラフの SetTransformROSに、LHandTransformRHandTransform、および HeadTransform 変数を設定します。
image.png

image.png
  1. イベントグラフで、右クリックして Custom Event を追加し、UpdateHeadHandsという名前を付けます。この関数はクライアントビルドで実行され、サーバーとユーザー間の新しいヘッドトラッキング位置とハンドトラッキング位置を更新します。現在のマップ内のユーザーごとに一定の間隔で呼び出されます。
    1. Is Locally controlledという条件のブランチノードを追加します。これが true と評価された場合、現在の呼び出しはローカルユーザーに対するものです。false の場合、リモートユーザー用です。
    2. Trueブランチで、MotionControllerLeftMotionControllerRight、および Camera 用の GetWorldTransform ノードを作成し、それぞれ LHandTransformRHandTransform、および HeadTransform に設定します。これにより、HMD の現在のトラッキング位置が取得され、サーバーへの複製用に作成した変数が更新されます。
    3. 最後の set 関数から、LHandTransformRHandTransform、および HeadTransform を入力として SetTransformsROSを呼び出し、更新されたトラッキングをサーバーに送信します。
image.png
  1. False ブランチで、MotionControllerLeftMotionControllerRightCamera SetWorldTransform ノードを作成し、それぞれ LHandTransformRHandTransform、および HeadTransformに設定します。これにより、リモートユーザーの HMD モデルが、サーバーから受信した最新の追跡位置に更新されます。
image.png
  1. EventTick ファンクションを UpdateHeadHands ファンクションに接続します。これにより、イベントティックの頻度に応じて UpdateHeadHands 関数が繰り返し呼び出されるため、追跡はサーバーとクライアント間で継続的に同期されます。
image.png
  1. Save、Compile ののちVRPawn ウィンドウを閉じることができます。

Part 5 : サーバーのパッケージ化とアップロード

サーバーが各クライアントの3Dトラッキングを同期できるようになったため、複数のクライアントを接続してもお互いを確認できます。サーバーの設定を完了するには、Part 1 で VR プロジェクトを Linux サーバービルドとしてパッケージ化し、ビルドを EC2 インスタンスにアップロードする必要があります。Linux 用にコンパイルするには、前提条件からクロスコンパイルツールチェーンをインストールしたことを確認します。

  1. Unreal Engine のドキュメントの Setting Up Dedicated Servers の “ “Select the Development Editor build configuration” セクションに従って、サーバービルドターゲットを作成します。このセクションでは、Visual Studio に Windows 用のサーバーバイナリを構築するための指示が記載されています。Windows ではサーバーを実行しないため、以降の手順は省略できます。
  2. Visual Studio で、UE5 ソリューションのコンテキスト (右クリック) メニューを開き、Build を選択します。これにより、Unreal Engine は作成したサーバーターゲットをコンパイルできます。これをスキップすると、サーバーをパッケージ化しようとしたときにビルドエラーが表示されることがあります。プリコンパイルされた Unreal Engine バイナリは専用サーバービルドをサポートしていないため、このプロジェクトにはソースビルドが必要であることに注意してください。
image.png
  1. Unreal Editor を再起動して新しいサーバービルドターゲットを検出し、エディタのツールバーで Platformドロップダウンをクリックして Linux を強調表示します。
    1. Binary Configuration では、Developmentを選択します。
    2. Build Target<projectname>Server を選択します。
    3. Package Project をクリックします。
    4. Linux サーバービルドを保存する場所を選択します。ハードウェアによっては、ビルドに最大で数時間かかります。
image.png
  1. PowerShell を起動し、サーバービルドを保存したフォルダー (プロジェクトの Binaries フォルダーなど) に移動します。次に、完成したビルドを含む Linux フォルダーを圧縮します。
    Compress-Archive -Path Linux -DestinationPath Linux.zip
  2. zip をサーバーにアップロードします。<vr-demo-kp.pem> は作成したキーのフルパスに置き換え、<public-ipaddress>は Part 1で作成したパブリック IPv4 アドレスに置き換えてください。その後、EC2 インスタンスにリモート接続します。
    scp-i <vr-demo-kp.pem>Linux.zip ec2-user@<public-ipaddress>: ~
    ssh -i <vr-demo-kp.pem> ec2-user@<public-ipaddress>
  3. EC2 インスタンスで VR サーバスクリプトを起動します。<projectname> を独自のプロジェクト名に置き換えてください。
    unzip Linux.zip
    chmod +x -R Linux/
    Linux/<projectname>.sh

この最後のコマンドは、現在 EC2 インスタンスでサーバービルドを実行しており、クライアントの接続を待っているため、終了しません。クライアントの接続時に、ここからサーバーログを監視できます。

Part 6 : Meta Quest 2 クライアントビルドのパッケージ化とロード

サーバーのセットアップが完了したら、サーバーに接続するためのクライアントビルドを作成する必要があります。このプロジェクトでは OpenXR を使用するため、作成したサーバーは OpenXR がサポートするあらゆるヘッドセットをサポートできます。このガイドでは、Meta Quest 2のクライアントのパッケージ化に焦点を当てています。別のヘッドセットを使用している場合、これらの手順は異なる場合があります。以前にQuest向けにAPKを開発したり、Questにサイドロードしたりしたことがない場合は、前提条件にリンクされているデバイス設定を行い、デバイスのターゲットAPIレベルに合わせてAndroid SDKとNDKをセットアップしてください。

  1. Unreal Editorのツールバーで、Platform ドロップダウンをクリックし、Android を強調表示します。
    1. Flavor Selection では、Android(ASTC) を選択します。
    2. Binary Configurationでは、Developmentを選択します。
    3. Build Target で、<projectname> を選択
    4. Package Project をクリックして、クライアントのビルドを開始します。クライアントが正常にビルドされたら、Unreal Editor を閉じることができます。

<Tip>これでビルドが開始されない場合は、プロジェクト設定で SDK パスを手動で指定する必要がある場合があります。Platform カテゴリで Android SDK を選択すると、SDKConfig が表示されます。次に、インストール先のパスを Android NDKAndroid SDK、および JAVA の場所として入力します。

image.png
  1. Android パッケージをQuestにロードします。
    1. ヘッドセットの電源を入れた状態で、ローカルマシンに接続します。
    2. Questで、Allow USB data sharing を選択して、APKを転送する権限を許可します。
    3. ローカルマシンの Android ビルドフォルダーで、Install_<projectname>-arm64.bat という名前のバッチスクリプトをダブルクリックします。
  2. 新しいオンライン VR アプリケーションを試してみてください。
    1. Meta Quest 2 ヘッドセットのアプリケーション画面で、Unknown sources をフィルタリングします。
    2. プロジェクト名でアプリを起動します。起動時には、OfflineMap で生成されます。
    3. 左側のコントローラーを使用してメニューを開き、パート 3 で作成した Connect ボタンを選択してサーバーに接続します。接続に成功すると、OnlineMapで生成されます。Hello, VR World!

<Tip>ヘッドセットが複数ある場合は、マルチプレイヤー操作をテストできます。他にQuest 2がある場合は、batスクリプトを使用して同じAPKをインストールできます。他のヘッドセットを使用している場合は、それぞれのデバイス用にクライアントビルドを再パッケージ化する必要があります。

image.png

おめでとうございます!これで、Unreal Engine VR サーバーが AWS 上で動作し、Meta Quest 2 からサーバーに正常に接続できました。これで、次の XR アプリケーションを AWS で構築してデプロイする準備が整いました。

クリーンアップ

VR サーバーの試用が完了したら、追加料金が発生しないように vr-demo-server EC2 インスタンスを停止または終了してください。

最後に

このブログでは、OpenXR 対応のUnreal Engine VR サーバーを AWS 上で設定、ビルド、デプロイし、クライアントとして Meta Quest 2 に接続する方法について説明しました。AWS の空間コンピューティングに関するその他のブログについては、AWS 空間ブログをご覧ください。また、次のゲームを AWS で構築する方法の詳細については、AWS for Games ページをご覧ください。

著者について

Eric Kim
Eric は、ゲーム業界の顧客に焦点を当てたソリューションアーキテクトであり、熱心なゲーマーでもあります。ゲーム開発者やパブリッシャーと協力して、スケーラブルなゲームやサポートサービスを AWS 上で構築しています。主にAI/ML、データ分析、AR/VRのアプリケーションに焦点を当てています。彼のお気に入りのゲームには、リーグ・オブ・レジェンド、スタークラフト、ポケモン、FIFA、スター・ウォーズジェダイ:フォールン・オーダーなどがあります。
Zack Anderson
Zack は AWS のソリューションアーキテクトであり、コンピューターサイエンス、ネットワーキング、およびシステム管理のバックグラウンドを活かして、主に ISV やデジタルネイティブのお客様と AWS でのビジネスの移行、最新化、運用を行っています。また、AWS for Games と協力して技術コンテンツを制作しています。
Alex Pieri
Alex は AWS のソリューションアーキテクトであり、お客様の AWS クラウド環境の計画、構築、最適化を支援しています。さらに、AWS でのゲームのホスティングと運用の背後にあるテクノロジーにも興味があります。
Chanh Tran
Chanh は AWS のソリューションアーキテクトで、ゲーム開発と AWS サービスとのゲームエンジンの統合に関心を持っています。

このブログの翻訳はソリューションアーキテクトの大井が担当しました。