Amazon GameLift を使って「最短」でマルチプレイヤーゲームを作る
Author : 秋山 周平
ゲームが大好きなみなさま、こんにちは!Game Solutions Architect の秋山周平です。
本タイトルが読者であるあなたの目に留まったということは、ゲームを作ってみたいという熱い気持ちを心のどこかに秘めているのではないかと思います。
本記事では、そんな皆さまの熱い気持ちを形にするため、 AWS が提供するマルチプレイヤーゲーム用のクラウドサーバー管理サービスである Amazon GameLift とゲームエンジンである Unity を使用し、マルチプレイ環境を構築するまでの手順をできる限り最小限の手順でご紹介します。本ハンズオンを実施することで、各ゲームクライアントで操作しているキャラクターの位置が他のゲームクライアントへ共有されていることを以下のように確認できます。
本来、マルチプレイ要素を伴うゲームを一般にリリースする場合は、Amazon GameLift が担当するゲーム用のクラウドサーバーの管理以外にも、プレイヤーアカウントの作成、プレイヤー認証、プレイヤーマッチング、プレイヤーに紐づくスコアの保存、サーバー側として動作するアプリケーションの作成、など様々な要素を同時に検討する必要があります。以下の図はマルチプレイヤーゲームで一般的に必要な機能を AWS 上のサービスで実現する場合の構成例になりますが、認証認可、プレイヤーデータ管理、マッチング、etc・・・と多数の機能を実装する必要があることがわかります。
AWS の各サービスを利用することでこれらの機能を実装するハードルは以前よりかは確実に下がってきています。しかしながら、私自身も実際にそうでしたが、マルチプレイ環境を作りたいと初めて検討したタイミングでいきなりこのような構成を検討し、各コンポーネントについて一度に学習しようとすると、実現までのハードルが非常に高く見えてしまい、挫折してしまうかもしれません。私は挫折しました。また、習得までの時間が膨大になってしまい、気づいた時には熱意が冷めてしまっている、といった状況に陥るかもしれません。
本記事はそんな、マルチプレイ環境の構築には興味があるけど難しそう・・・といった状況の読者向けに、マルチプレイゲームを体験することのみに注力し、以下の通りほぼ GameLift のみを使用したハンズオンを紹介します。
すでに GameLift を活用されている方にとっても、理解をより深めていただけるような内容となっておりますので、ぜひ手を動かしてお試しいただければと思います。
目次
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »
毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。
1. 注意事項
本記事では以下の操作が行えることと、環境が整っていることを前提としています。
- AWS のマネジメントコンソールの使用 (AWS アカウント作成方法はこちら »)
- 対話型シェルの使用
- Unity Editor の使用とプロジェクトのビルド
本記事で扱うサンプルスクリプトについては以下の環境で動作確認しています。しかしながら、ネットワーク通信を伴うマルチプレイゲームの性質上、クライアントのネットワーク環境やファイアウォールによっては動作しない場合があります。特に、アプリケーション起動後に位置情報の送受信が始まらない場合はネットワークの経路上に問題がある可能性が高いため、ファイアウォールの設定などを確認してみてください。
- macOS Big Sur / Unity Editor 2021.3.5f1
- Windows 10 / Unity Editor 2021.3.5f1
2. Amazon GameLift の紹介
冒頭でも紹介した通り、 Amazon GameLift はマルチプレイ環境に必要なサーバー側のゲームアプリケーションならびにその実行環境を管理するサービスです。「管理」の部分には幅広いタスクが含まれますが、例えば以下のような作業をゲーム開発者に代わって GameLift が実施します。
- ゲームサーバーでのゲームアプリケーションの実行
- プレイヤーのマッチメイキング
- マッチングされたプレイヤーのゲームアプリケーションへの配置
- ゲームセッションを基準としたゲームサーバーのスケーリング
- DDoS からのゲームサーバーの保護
さらに、 GameLift ではゲームサーバーで動作するアプリケーションの種類として、「カスタムゲームサーバー」と「リアルタイムサーバー」を用意しています。後者のリアルタイムサーバーは Node.js ベースの JavaScript でサーバー側のロジックを記述することが可能で、更にクライアント側で専用の SDK を使用することで接続管理やメッセージの送受信を手軽に実装することが可能となっています。
本記事では、なるべく簡単にマルチプレイ環境を実現するため、後者の「リアルタイムサーバー」を使用します。カスタムゲームサーバーに興味がある方は以下のリポジトリをぜひご覧ください。
https://github.com/aws-samples/aws-gamelift-sample
https://github.com/aws-samples/amazon-gamelift-unity
https://github.com/aws-samples/aws-gamelift-and-serverless-backend-sample
3. 本記事で実施する手順の概要
本ハンズオンは最短 40 分 程度で動作確認が可能なコンテンツとなっていますが、GameLift や Unity に馴染みのない方は是非自分のペースでゆっくり進めていただくことをお勧めします。
- マルチプレイ化のベースとなる、シングルプレイ用のプロジェクトを確認する
- サーバー側で動作するスクリプトの内容を確認する
- AWS アカウントの準備と操作用の IAM ユーザーを作成する
- AWS アカウント内に GameLift のリソースを作成する
- マルチプレイ化したプロジェクトを確認しビルドする
- AWS CLI コマンドを実行し、手動でゲームのルーム作成とプレイヤーの登録を行う
- 複数の端末から操作を実施し、同じマップ上のプレイヤーの情報が互いのアプリケーションに同期されていることを確認する
- 使用したリソースを片付ける※
※作成したリソースを放置することは意図しないコスト発生につながりますので、確実に削除する習慣をつけましょう。
4. マルチプレイ化のベースとなる、シングルプレイ用のプロジェクトを確認する
まずは、本記事冒頭の サンプルコード の zip ファイルをダウンロードしてください。zip ファイルを解凍すると、2 つのフォルダがありますが、そのうち「SinglePlayerGame」がマルチプレイ化のベースとなるアプリケーションのプロジェクトです。
なお、本記事では macOS 上での作業を参考として記載しますが Windows を使用している場合も同様の手順を実施可能です。
クリックすると拡大します
こちらは Unity Project となっていますので、お使いの Unity で開くことが可能です。なお、バージョンは 2021.3.5f1 バージョン以上の Unity をご利用ください。
プロジェクトを開いた後は、環境によってレイアウトの違いはありますが概ね以下のこのような形となっているかと思います。正常に開いたにもかかわらず何も表示されない場合は、Assets フォルダ直下にある「SampleScene」シーンファイルをダブルクリックで開いてください。
クリックすると拡大します
クリックすると拡大します
プロジェクトには以下のスクリプトが含まれています。
- CharacterManager.cs : プレイヤーの入力を十字キーで受け付け、キャラクターを移動させます
- CharacterAnimation.cs : キャラクターの移動にともない簡易的なアニメーションを行います
- DisplayDebugLog : 実行中のログメッセージを画面に出力します
次に、本ゲームを実際にプレイしてみましょう。 Unity では画面中央上部の三角マークの「Play」ボタンを押すことで、現在表示されているシーンでゲームを実行することができます。十字キーを押すことであらかじめ定義されたマップの上をキャラクターが移動できることが確認できます。
しかしながら、現状プレイヤーが一人しかいないのでなんとも味気ない状態ですね。
ここからこのゲームをマルチプレイ化し、このマップ上に複数のプレイヤーを同時に存在させてみましょう。
5. AWS アカウントの準備と操作用の IAM ユーザーを作成する
まず、使用する AWS アカウントを用意します。何かしら他の AWS リソースが動いているアカウントですと、今回の作業で影響を与えてしまう可能性が 0 ではないため、サンドボックス的なアカウントで試していただくことをおすすめします。もし、そのような AWS アカウントをお持ちでない方は、アカウント作成ハンズオン をご用意していますので、こちらからアカウント作成を検討ください。
その後、操作に必要な IAM 権限のあるユーザーでログインできることを確認してください。
本記事では以下の IAM ポリシーに相当する権限が操作する IAM ユーザーに付与されていれば問題なく作業を実施できます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "gamelift:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "cloudshell:*",
"Resource": "*"
}
]
}
6. サーバー側で動作するスクリプトの内容を確認する
次に、ゲームサーバー上で動作するアプリケーションを確認します。こちらは「MultiPlayerGame」というフォルダに配置されている「server.js」が対象となるスクリプトとなります。 GameLift のリアルタイムサーバー を利用する場合、 本スクリプトをアップロードすることで、 GameLift 側が本スクリプトをゲームサーバー上で自動で起動します。
ゲームのルームが作成された、プレイヤーがゲームのルームに入室した、といったイベントが発生した場合に、スクリプトに記述されているコールバックが実行されます。そのため、各コールバックには状況に応じた処理を記載する必要があります。
今回スクリプトにはすでに必要な処理を記載しています。簡略化のため、サーバー側のスクリプトには複雑は処理は記述せず、プレイヤーからのメッセージを受信したら全プレイヤーに転送する処理を以下に抜粋した部分で実装しています。なお、ゲーム全体の進行管理や時間管理をしたい場合には、必要に応じてサーバー側でゲームの状態を管理する処理を追加する必要があります。
function onMessage(gameMessage) {
session.getLogger().info("[app] SendStringToAll: DefaultGroupId " + session.getAllPlayersGroupId());
session.sendGroupMessage(gameMessage, session.getAllPlayersGroupId());
}
そのほかのコールバックがいつ呼び出されるかについては こちら をご確認ください。
7. AWS 側に GameLift のリソースを作成する
ここから AWS 側で必要なリソースを作成します。まずはじめに、 「6. サーバー側で動作するスクリプトの内容を確認する」で確認したサーバー側のスクリプトを GameLift へアップロードします。アップロードしたファイルは「スクリプト」として GameLift で管理されます。
こちらはマネジメントコンソールの GameLift のページからも手動で行うことができますが、今回は環境ごとの差分がなるべく発生しないようにするため、 AWS CLI コマンドを CloudShell 上で実施する方法を紹介します。
CloudShell はマネジメントコンソールのトップページで検索することで使用できます。無事 CloudShell のページを開くことができると対話型シェルが表示されている画面が確認できます。
クリックすると拡大します
クリックすると拡大します
まずは CloudShell 上で AWS CLI コマンドを実行するにあたって、リソースを作成するリージョンを指定します。「Default region name」以外の項目については空欄で構いません。今回は ap-northeast-1 リージョンを指定しますが、 GameLift がサポートしている他のリージョンでも動作を確認しています。
aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]:
次に、CloudShell 環境へ「server.js」 をアップロードします。ページ右上の「Actions」より「Upload file」を選択し、ファイルのアップロードを実施してください。
成功した場合、こちらのように /home/cloudshell-user/ ディレクトリに 「server.js」が配置されます。念の為 cat で内容を確認しておきましょう。
クリックすると拡大します
アップロードが無事成功したら、以下コマンドにて CloudShell 上で zip ファイルを作成し GameLift に登録します。
zip server.zip server.js
SCRIPTID=$(aws gamelift create-script --name "minimalsamplegame" --zip-file fileb://server.zip --query 'Script.ScriptId' --output text)
次に、アップロードしたスクリプトを動作させるためのゲームサーバーのまとまりである「フリート」を作成する必要があります。こちらは CloudShell で以下のコマンドを実行することで作成できます。
aws gamelift create-fleet --name "minimalsamplegame" \
--description "Minimal Multiplayer game sample" --ec2-instance-type "c5.large" --fleet-type ON_DEMAND \
--script-id $SCRIPTID --certificate-configuration "CertificateType=DISABLED" \
--runtime-configuration "GameSessionActivationTimeoutSeconds=60,MaxConcurrentGameSessionActivations=2,ServerProcesses=[{LaunchPath=/local/game/server.js,ConcurrentExecutions=4}]" \
--new-game-session-protection-policy "FullProtection" \
--resource-creation-limit-policy "NewGameSessionsPerCreator=3,PolicyPeriodInMinutes=15" \
--metric-groups "minimalsamplegame-fleet"
数十分ほど待つとフリートが完成します。こちらは以下マネジメントコンソールのページからも確認することができます。
ここまでで、GameLift 側の事前準備は完了となります。
クリックすると拡大します
8. マルチプレイ化したプロジェクトを確認しビルドする
ダウンロードしたプロジェクトの「MultiPlayerGame」というフォルダには、マルチプレイに対応させた Unity プロジェクトを用意しています。
こちらを同様に Unity で開くと、「SinglePlayerGame」には存在しない、次のスクリプトが新しく Assets 配下に追加されていることが確認できます。
- MultiPlayerGameController.cs : 自身の位置の送信、他プレイヤーの位置の受信と反映、ルームへの入室確認などゲームにおけるマルチプレイ部分の管理を行います。
- RealTimeServerConnectionManager.cs : GameLift Realtime Client SDK をラップし、 MultiPlayerGameController.cs から利用できる関数やコールバックを定義しています。
プロジェクトをひととおり確認したら、Unity でビルドを実施し実行ファイルを作成しましょう。
本記事では Mac ならびに Windows 向けにビルドされたアプリケーションで動作確認を行っています。
お疲れさまでした ! ここまでで全ての事前準備は完了しました。GameLift 側には接続を受け付けるゲームサーバーが存在し、接続するためのクライアント側のアプリケーションも実行可能な状態になっています。
ここからは、実際に動作を確認してみましょう。
9. AWS CLI コマンドを実行し、手動でゲームのルーム作成とプレイヤーの登録を行う
まずマルチプレイを始めるにあたって、プレイヤーが集合するためのルーム、つまり GameLift のゲームセッションを作成する必要があります (以降、GameLift におけるルームを ゲームセッションとして記載します)。次に、ゲームに接続するプレイヤーは、自身のプレイヤー ID と加入先のゲームセッション ID を指定し GameLift にプレイヤーセッションを作成することで、指定したゲームセッションへ参加することを GameLift へ伝えます。
本来であれば、こちらの作業は冒頭の図のように別途 API サーバーを用意し、クライアントからのリクエストを認証した上で GameLift へ伝える必要がありますが、今回は簡単のため AWS CLI を用い手動で登録作業を実施します。なお、以下の図の手順のうち、手順 2 ~ 4 についてはプレイヤーの人数分だけ繰り返し実施する必要があります。
<手順 1 ゲームセッション作成>
再び、マネジメントコンソールで CloudShell の画面を開いてください。まずは以下のコマンドを実行し、先ほど作成したフリートの ID を取得し変数へ格納してください。マネジメントコンソールのフリートの一覧ページから作成したフリート ID の確認が可能なため、CloudShell の画面を一度閉じてしまった場合にはマネジメントコンソールよりフリート ID をコピーし変数へ格納してください。
FLEETID=$(aws gamelift list-fleets --script-id $SCRIPTID --output text --query 'FleetIds[0]')
echo $FLEETID
次に、保存したフリート ID を使用しフリートにゲームセッションを作成します。
今回は、ゲームセッション作成後 4 分間プレイヤーの接続がない場合に自動でゲームセッションが終了する動作のため、ゲームセッション作成後はすみやかにプレイヤーセッションの作成と接続を行ってください。
GAMESESSIONID=$(aws gamelift create-game-session --fleet-id $FLEETID --maximum-player-session-count 4 --query 'GameSession.GameSessionId' --output text)
echo $GAMESESSIONID
<手順 2 プレイヤーセッション作成>
ゲームセッションを作成したら、次はプレイヤーのセッションをゲームセッションに登録します。
aws gamelift create-player-session --game-session-id $GAMESESSIONID --player-id testuser1
<手順 3 ゲームクライアントの起動とゲームサーバー情報の登録>
次に、作成したプレイヤーセッションを登録するゲームクライアントを立ち上げましょう。
Max OS の場合、ターミナルから以下コマンドを実行することで、アプリケーションの多重起動が可能です。
cd <アプリケーションが存在するディレクトリ>
open -n <ビルドしたアプリケーション名>.app
Windows の場合は実行ファイルをダブルクリックすることでアプリケーションの多重起動が可能です。
無事アプリケーションが立ち上がったことを確認したら、CloudShell へ戻り「create-player-session」の結果として出力された JSON テキストをコピーしましょう。
そして、こちらを参考に起動したアプリケーションの画面下部にある、 「CreatePlayerSession の結果をここにペースト」と記載されたフォームに貼り付けてください。
クリックすると拡大します
<手順 4 ゲームサーバーへ接続>
ここまでうまく設定できている場合、「Connect Server」をクリックすることでフリートのゲームサーバーへ接続できます。成功した場合、画面下半部にプレイヤーの位置情報のログが多数表示されます。
<うまく接続できない場合>
まずは以下の点を確認してみてください。
- ゲームセッションが自動終了する 4 分以内に 1 つ以上のクライアントがゲームサーバーへ接続できているか確認する
- クライアント側 OS やプロキシなどのネットワークの経路上で接続をブロックしている設定がないか確認する
また、今回ハンズオンで使用した「server.js」は GameLift が管理する S3 バケットへログを保存しています。そのためこちらを確認する原因を絞り込むことが可能です。
GameLift が保存したログファイルについては、以下 AWS CLI コマンドにて取得できます。
curl "$(aws gamelift get-game-session-log-url --game-session-id $GAMESESSIONID --query 'PreSignedUrl' --output text )" --output gamesessionlog.zip
こちらのコマンドを CloudShell 上で実行した場合は、そのまま CloudShell 上で zip ファイルをコマンドで展開し確認するか、 zip ファイルをローカルのマシンにダウンロードして確認することができます。
最後に、うまく接続できた場合は上記手順 2~4 を加入するプレイヤーの数だけ繰り返します。
10. 同じマップ上のプレイヤーの情報が互いのアプリケーションに同期されていることを確認する
ここまでの手順を完了すると、起動したアプリケーションの画面に同じゲームセッションに存在するプレイヤーの数だけキャラクターが表示されていることが確認できるかと思います。
さらに、十字キーを使用しいずれか一つのアプリケーションのキャラクターを移動させてみましょう。自分が操作したキャラクターの位置が他のアプリケーションに反映されていることが確認できます。
おめでとうございます ! これであなたも立派なマルチプレイヤーゲームクリエイターです。
本ハンズオンは一人でも動作確認まで可能ですが、ぜひ知り合いと一緒に複数人で動作を体験してみましょう !
クリックすると拡大します
11. リソースを削除する
使ったリソースはきちんと片付けないと使い続けることになり不要なコストが発生するため、確実に片付ける癖をつけましょう。
慣れている方は、これまでと同様に CloudShell 上で AWS CLI コマンドを実行することで削除可能です。また、マネジメントコンソールの「フリート」、「スクリプト」のページからも同様にそれぞれのリソースを削除できます。
フリートの削除
curl "$(aws gamelift get-game-session-log-url --game-session-id $GAMESESSIONID --query 'PreSignedUrl' --output text )" --output gamesessionlog.zip
スクリプトの削除
aws gamelift delete-script --script-id $SCRIPTID
無事削除が完了すれば、ハンズオンの全ての行程は終了です。
お疲れさまでした !
12. まとめ
今回、マルチプレイ環境をできる限り最小の手順で構築する方法をご紹介しました。
冒頭で記載した通り、本番環境での運用を見据えた開発の場合は様々な要件やコンポーネントが必要となってきますが、マルチプレイのゲームがどのようなものであるかまず知りたいという場合に、本記事はきっと助けになると思います。
特に、 GameLift のリアルタイムサーバーは、サーバー側アプリケーションの構築とクライアントとの連携が JavaScript ベースのスクリプトを記載するだけで実現できるため、とりあえず作ってみたい ! という方にぴったりの機能かと思います。
本記事を読み終えて、もっと GameLift を触ってみたい ! となった方は以下の GitHub リポジトリにあるチュートリアルやワークショップ、AWS ブログなどをご覧ください。より本格的な構成のゲームの構築を実践できます。
- https://catalog.us-east-1.prod.workshops.aws/workshops/bccf7c14-8f6f-441b-a4ff-fd6a2b402892/ja-JP
- https://github.com/aws-samples/aws-gamelift-sample
- https://aws.amazon.com/jp/blogs/gametech/creating-a-battle-royale-game-using-unity-and-amazon-gamelift/
本記事を足がかりにこれらのハンズオンもお試しいただき、ぜひみなさんのゲーム作り欲を高めていっていただけると嬉しいです。そして、作成したゲームをどんどん公開し業界を盛り上げていきましょう !
ゲーム開発者向けのその他の記事はこちら
- 選択
- Amazon DynamoDB で作るサーバーレスなゲーム用アチーブメントマイクロサービス
- AWS の知識ゼロから始める AWS GameKit
- Amazon GameLift を使って「最短」でマルチプレイヤーゲームを作る
- Amazon DynamoDB で作るサーバーレスなゲーム用フレンドマイクロサービス
- Amazon GameSparks でインフラを意識せずにゲームのバックエンドサービスを開発しよう
- 魔法で作る Amazon DynamoDB の 簡単ゲームインベントリ
- レベル 1 から作るゲームのクエスト手帳
- サーバーレスなゲームのギルド検索
- 一緒に学び考える ! ゲームの AI/ML 活用
- 3 ステップで始める AI モデル開発 ! 始める前に知っておくべきコト !
- 実践 ! 機械学習でゲームの休眠ユーザーを予測してみよう
- Amazon GameLift Anywhere でサクッとマルチプレイゲームを開発しよう
- ゲーム分析を Amazon Aurora と Amazon Redshift の Zero-ETL 統合ではじめよう
- Amazon Redshift を活用したゲームの行動ログ分析
- Amazon QuickSight によるゲーム分析ダッシュボードの構築
- 品質管理に生成 AI は使えるのか !? テキストチェックを生成 AI にやらせてみた
- 生成 AI を用いたヘルプソリューションを作成する
- 世界に 1 つだけの AI アシスタント作成 ~オリジナルにカスタマイズ
- マルチモーダルな生成 AI 活用の入門編! - 画像認識と画像生成
- Amazon S3 と Amazon CloudFront を活用したグローバル向けゲームビルドバイナリ共有環境の構築
- Terraform を利用した Amazon EKS の構築
- Amazon Bedrock でゲームの BGM を作ってみました !
- Amazon EC2 ではじめる Unreal Engine Pixel Streaming 入門
- Agones on Amazon EKS で構築するマルチプレイゲームの専用ゲームサーバー
- AWS Summit Japan 2024 Game Industry Booth の舞台裏
筆者プロフィール
秋山周平
アマゾン ウェブ サービス ジャパン合同会社
技術統括本部 ソリューションアーキテクト
以前は AWS サポートにて広範のお客様をご支援していました。現在は特にゲーム業界のお客様に対して、ソリューションアーキテクトとして技術的なご支援をしています。
好きなサービスは Amazon GameLift と Amazon Cognito。週末は大自然の中にいます。
AWS を無料でお試しいただけます