Amazon GameLift Streamsを使ってUnityのアプリをストリーミング配信してみた
2025年3月6日にAWSからゲーム開発者向けの新サービス「Amazon GameLift Streams」が発表されました。簡単な操作で高品質・低遅延の提供を受けられるということで、様々な映像を扱うテレビ局の私たちでも有用なサービスではないか?と思い、早速使ってみました。
Amazon GameLift Streams
Amazon GameLift StreamsはAWSが提供する新しいクラウドゲームストリーミングサービスです。自社のゲーム配信インフラ構築に時間や社内リソースを費やすことなく、マネージメントコンソールから数回クリックするだけで、Unityなどのさまざまな3Dエンジンで構築されたゲームを、フルマネージド型かつクラウドベースのGPUインスタンスにデプロイすることができます。そしてiOS、Android、PCなどのデバイスに、最大1080pの解像度と60フレーム/秒のゲームストリーミングが可能となりました。
詳細はこちらのプレスリリースをご覧ください
Unity
Unityとはゲーム業界で有名な、2Dと3Dの両方のゲーム開発に使用できる強力なゲームエンジンをもつ開発プラットフォームです。Unityのもつリアルタイムレンダリング能力や柔軟な拡張性は、ゲーム開発だけでなく映像製作や放送・配信などの現場でも十分に応用可能です。近年ではVR・ARコンテンツ制作の主要プラットフォームとしても注目されており、様々な業界でのシミュレーションツールとしても活用されるなど、注目度が高いソフトウェアとなっています。
開発内容
今回はUnityで作ったゲームを簡単にAmazon GameLift Streamsにデプロイしてブラウザ上で触ることを目的とするため、簡易なスイッチングシステムをUnityで作りました。
(今回はAmazon GameLift Streamsが目的なので詳細は省きます)
[Unityの開発画面(簡単なカメラスイッチングアプリ)]
Amazon GameLift Streamsの実装
まず、Unityでビルドしたときに作られた実行ファイルを一括でAmazon S3にアップロードします。
[Unityのビルド画面]
[S3へのファイルアップロード]
次にマネジメントコンソール上でAmazon GameLift Streamsアプリケーションの作成を行います。
[アプリケーションを作成] を選択し、[ランタイム設定]でランタイム環境を選択します。今回はgen4n_win2022にしました。
全般設定のベースパスと実行可能な起動パスは先ほどアップロードしたS3バケット内のフォルダと、Unity実行ファイルへのパスを設定します。
そして最下部の[アプリケーションを作成]を選択するとすぐにアプリケーションが作成されました。
[Amazon GameLift Streamsのアプリケーション作成画面]
アプリケーションのセットアップが完了したら、アプリケーションの実行・ストリーミングのために、ストリームグループを作成します。ストリームグループの設定画面から[ストリームグループを作成]を選択します。
ストリームグループの簡単な説明を定義した後、ストリームクラスを選択します。今回はアプリのランタイムをMicrosoft Windows Server 2022 Baseを選択していたことから、今回はgen4n_win2022を選択しました。
[ストリームグループ画面]
ちなみにgen4n_win2022はg4dn.2xlargeのEC2が使われています。東京リージョンだと2025年3月現在、g4dn.2xlargeのEC2インスタンスのオンデマンド料金は1時間あたり$1.383で、Amazon GameLift Streamsのgen4n_win2022は$2.25となっています。
そしてセットアップしたアプリケーションをリンクし、ストリームグループの追加ロケーションを設定し(今回は追加せず東京のみ)、[ストリームグループを作成]を選択すると作成されます。
[アプリケーションリンク設定画面]
[ストリーム設定構成確認画面]
テストストリーム
ストリームグループを設定すると、次はゲームストリーミングをテストしてみます。
コンソールの[ストリームテスト]ページから該当するアプリケーションを選択し、[ストリームグループを選択する]を押して、次のページで[テストストリーム]を押すとアプリケーションが実行されました。
Web サーバーとクライアントの実装
最後にAmazon GameLift Streams のストリーミングサービスを統合するウェブクライアントアプリケーションを作ります。AWS提供のサンプルコードには、シンプルな Amazon GameLift Streamsバックエンドウェブサーバーとシンプルなウェブクライアントが入っており、これを使用することで簡単にストリームを開始することができます。
「GitURL」
https://github.com/aws-samples/sample-gameliftstreams-web-application
ここでは、主要処理であるWebRTCストリームとUnity側(GameLift Streams上で動作)との操作連動処理について一部分を抜粋します。
[server.js]
app.post('/api/CreateStreamSession', function (req, res) { // 省略… // GameLiftStreamsのストリームセッション開始用リクエストデータを作成 const requestData = { Identifier: streamGroupId, AdditionalLaunchArgs: req.body.AdditionalLaunchArgs, AdditionalEnvironmentVariables: req.body.AdditionalEnvironmentVariables, UserId: req.body.UserId, Protocol: 'WebRTC', SignalRequest: req.body.SignalRequest, ConnectionTimeoutSeconds: config.STREAM_CONNECTION_TIMEOUT_SECONDS, SessionLengthSeconds: 3600, // セッション長は1時間(必要に応じて最大24時間まで設定可能) ApplicationIdentifier: req.body.ApplicationIdentifier, Locations: req.body.Locations, }; // GameLiftStreamsのAPIを呼び出してセッションを開始 gameliftstreams.startStreamSession(requestData, (err, data) => { if (err) { console.error('CreateStreamSession error:', err); res.status(config.GENERAL_ERROR_STATUS_CODE); res.json({ error: err.message }); } else { console.log(`CreateStreamSession success: Arn=${JSON.stringify(data.Arn)}`); // 接続トークンを生成し、セッション情報をインメモリのデータベースに保存 const connectionId = crypto.randomUUID(); connectionDatabase[connectionId] = { StreamGroupId: streamGroupId, StreamSessionArn: data.Arn, Timestamp: Date.now() }; // クライアントにトークンを返却。後続の/signalingやreconnectで使用される res.json({ Token: connectionId }); // トークンの有効期限は24時間後に自動削除される仕組み setTimeout(() => { delete connectionDatabase[connectionId]; }, 24*60*60*1000); } }); });
-
セッション開始リクエスト
クライアントが/api/CreateStreamSession
エンドポイントに必要なパラメータ(ストリームグループID、WebRTCシグナリング情報など)を送信します。 -
Unityセッションの初期化
エンドポイント内でgameliftstreams.startStreamSession
が呼び出され、GameLift Streams上でUnity向けのWebRTCストリーミングセッションが開始され、シグナルレスポンスの送信が始まります。 -
接続トークンの生成と保存
セッション開始に成功すると、ユニークな接続トークンが生成され、ストリームグループID、セッションARN、タイムスタンプなどのセッション情報とともに、インメモリのconnectionDatabase
に保存されます。 -
シグナリング情報の取得
クライアントは/api/GetSignalResponse
エンドポイントを呼び出し、保存された接続トークンを元に、GameLift StreamsからWebRTCシグナリング情報(接続確立に必要なデータ)を取得します。 -
WebRTC接続の確立
取得したシグナリング情報を使用して、WebクライアントとUnity間でWebRTCハンドシェイクが完了し、リアルタイムな接続が確立されます。
この一連の流れにより、Webクライアントの操作がUnity側のストリーミングセッションにリアルタイムで反映される仕組みとなっています。
デプロイはAWS CDKを用いて行います。ターミナルで以下の 2 行のコマンドを実行するだけで、スタックのデプロイが完了し、必要なリソースがクラウドフォーメーション上で自動的に構築されます。
chmod +x deploy_cdk.sh ./deploy_cdk.sh sg-000000000
※以下、CDK実行時のIAMロールの権限忘れに注意してください。
・Amazon CloudFormationのフルアクセス権限 (cloudformation:*)
・AWS IAMロール作成権限 (例: iam:CreateRole、iam:PutRolePolicy など)
・AWS Lambda管理権限 (lambda:*)
・Amazon API Gateway管理権限 (apigateway:*)
・Amazon GameLift Streams権限 (gameliftstreams:*)
・AWS Lambdaのログ出力用Amazon CloudWatch Logs権限
クラウドフォーメーションのスタックデプロイはおおよそ3分ほどで完了し、共有可能なストリームURLが出力されます。ストリームURLにアクセスをすると、リモートスイッチャー画面が表示されます。こちらに、プレイヤーIDとアプリケーションIDを入れて配信開始すると、サーバーとのWebRTCセッションを繋ぎ、実際にブラウザからUnityのリモートスイッチャーアプリを動かすことができました。気になるスイッチングディレイに関してですが、体感的にいうと通常のハードスイッチャーとの違いを感じさせない瞬時キーボードスイッチングができました。また、同時接続利用により複数のプレイヤーが視聴できるので、プレイヤー間やアプリとのマルチ通信処理を実装すれば、さらに高度なインタラクティブコンテンツの開発が期待できそうです。何度も言いますが、Webブラウザ環境でUnity操作ができるのは感動です!
[リモートスイッチャー配信Webアプリ]
[キーボード「1」「2」「3」「4」でスイッチング]
まとめ
Amazon GameLift Streamsを使うことで、簡単に高品質・低遅延のUnityアプリのストリーミング環境を実装することができました。
本来、このサービスの使用用途は、Web上で通信ゲームができることが主目的かもしれません。しかし放送業界でもコンテンツ製作や放送・配信などで、映像と通信を融合したシステムを数多く使用しています。今後はこのようなサービスを活用していきながら、放送局のコンテンツを使ってインタラクティブな視聴体験であったり、ファンエンゲージメントを高めたコンテンツを作っていこうと思っています。
このようなゲーム製作を応用した映像製作技術は今後ますます広がっていくと思われます。今回の私の取り組みが、皆さんの次なる挑戦のヒントになれば幸いです。