こんにちは!金融ソリューション事業部の孫です。
ゲームが好きなみなさま、クライアント・サーバーモデルのマルチプレイゲームの制作に興味を持っていますか?
本記事では、熱意を持っていますが「難しそう・・・どうやって始めたらいいんだろうか、ゲームサーバーの構築はどうすればいいのか」という状況の読者向けに開発を体験するのハンズオンを紹介します。
皆さまの熱い気持ちを早く形にするため、AWSが提供するマルチプレイーゲーム用のクラウドサーバー管理サービスであるAmazon GameLiftとゲームエンジンであるUnreal Engines5を使用し、オンラインマルチプレイ環境を構築する最低限の手順でご紹介します。
注意事項
本記事では以下の操作が行えることと、環境が整っていることを前提としています。
- AWSのマネジメントコンソールの使用
- 対話型シェルの使用
- Unreal Engineの利用とプロジェクトのビルド
また、本検証を行う場合、使用するAWSの利用料金が発生する点に注意してください。
Amazon GameLiftとは
冒頭でも紹介した通り、Amazon GameLift(以下 GameLift) は、マルチプレイ環境に必要なサーバー側のゲームアプリケーションならびにその実行環境を管理するサービスです。
本来、マルチプレイ用ゲームサーバーの構築にあたり、プレイヤーアカウントの作成、プレイヤー認証、プレイヤーマッチング、プレイヤーのスコアなど様々な要素を同時に検討する必要がありますが、GameLiftの採用によってそれらの手間が要らなくなって以前より実装するハードルが下がってきています。
GameLiftを利用した開発の流れは、以下図のように4stepがあります。とてもシンプルにゲームの開発ができます。
更にクライアント側で専用の SDK を使用することで接続管理やメッセージの送受信を手軽に実装することが可能となっています。本記事では、GameLiftSDKの組込みでオンラインマルチプレイ環境を実現しました。
Unreal Engine5 とは
Unreal Engine は、Epic Gamesによって開発されているゲームエンジンです。
そもそも、ゲームエンジンが何かというと簡単に言うとゲームを作るためのソフトです。
ゲームエンジンを使用することで、ゲームを作るためのツールや環境が準備された状態でゲーム制作をすることができます。いわゆる、0からプログラミングをしなくて済みます。
Unreal Engineの特徴として、下記のようなものが挙げられます。
- 無料で使用できる
- ソースコードが公開されている
- プログラミングなしでもコンテンツ制作ができる
- グラフィックスが断トツで高品質
- 高品質なアセットが無料、有料ともに豊富
更に近年メタバースによる変革がリアルタイムの 3D技術が強く求められています。Unreal Engineによって高品質なVRコンテンツの制作が可能になります。
Unreal Engine5(以下UE5)はUnreal Engineの最新バージョンです。
実施手順
手順は、以下の通りです。
- UE5ソースコードのビルド
- UE5テンプレートからゲームサーバーを作成する
- GameLiftSDKをビルドしプラグインを生成する
- ゲームサーバーにGameLiftプラグインの組込み
- ローカルでゲームのテスト及びGameLiftへのアップロード
- AWS CLIコマンドによるゲームセッション作成と接続
AWSアーキテクチャ
本記事では、マルチプレイゲーム開発を体験することのみに注力し、以下の通りほぼGameLiftのみを利用して構築します。 ※Lambda、API Gateway、Cognitoに構築については別記事でご紹介します。
使用環境/ツール
- Unreal Engine 5.1.0
- windows10 21H2 x64
- RAM 16GM, SSD 1TB
- NVIDIA GeForce GTX 980M
- Gamelift SDK
- GameLift Cpp ServerSDK 3.4.2
- GameLift Unreal plugin 3.4.0
- Visual Studio 2019 version 16.11.21(以下VS2019)
- JavaSDK 1.8.0
手順1. UE5ソースコードのビルド
Unreal Engineの公式GitHubリポジトリより、Unreal Engineソースをクローンしてコンパイルします。
クローン:
git clone https://github.com/EpicGames/UnrealEngine.git
コンパイル:
UnrealEngineフォルダに移動 Setup.batをダブルクリックして実行 GenerateProjectFiles.batをダブルクリックして実行 UE5.slnをクリックしてVS2019で開いて以下の図の通りにビルド実行
※Unreal Engineのリポジトリへのアクセスは、権限が必要なので、済ではない方は、SignUpの手順に従ってアクセス権限を設定してください。
※ビルド時間はマシンのスペックによるが、参考までに、Epicの推奨スペックの情報があります(ビルド時間を短縮するため、最低限は500GB SSD、16GB RAMをおすすめします)。
手順2.UE5テンプレートからゲームサーバーを作成する
手順1で無事にUE5のビルドが完了後、「Local Windows Debugger」をクリックしてUnreal Editorを立ち上げます。
※Configure情報は以下であることを確認してUnreal Editorを立ち上げてください。Unreal Editorの画面から「ゲーム」⇒ 「サードパーソン」⇒「C++」⇒「新プロジェクト名入力」(今回は、プロジェクト名を「Gamelift_UE5」としました)でゲームサーバーのプロジェクトを作成します。
プロジェクト作成完了後、vs2019とUnreal Editorをクロースしてプロジェクトフォルダに移動します。
SourceフォルダのGamelift_UE5Editor.Target.csファイルを複製して、ゲームサーバー用のGamelift_UE5Server.Target.csビルドファイルを作成します。
任意のテキストエディタでGamelift_UE5Server.Target.csを開いて、「Editor」⇒「Server」を書き換えます
プロジェクトフォルダに戻して、プロジェクトファイルを右クリックし「Generate Visual Studio project files」でプロジェクトを再生成します
プロジェクトフォルダのGamelift_UE5.slnファイルをクリックし、VS2019を立ち上げます、そこで先ほど新規追加したゲームサーバー用のプロジェクトファイルが見えることを確認します
プロジェクトをビルドします
プロジェクトを再ビルドして後、Gamelift_UE5.uprojectをクリックしてUnreal Editorを立ち上げます
クライアントがゲームサーバーとの接続に成功したかを判別するため、"ゲームサーバー接続前の「オフラインマップ」"と"接続後の「オンラインマップ」"を別々に作成します(既存のマップの複製で作成)
プロジェクトの「マップ&モード」でマップの利用ルールを設定します(「サーバーのデフォルトマップ」を、先ほど複製して作成したレベルに変更します)
パッケージ化の時に、作成したマップを含まれるように、「パッケージ化」で「マップのパス」を設定します。
Windows向けにプロジェクトをパッケージ化します
- バイナリコンフィグレーション:開発
- ビルドターゲット: Gamelift_UE5Server
※パッケージ化の所要時間はマシンのスペックによります。
手順3.GameLiftSDKをビルドしプラグインを生成する
※GameLiftSDK開発ドキュメントのセットアップ要件で、現在UE4.25のみの対応となっておりますが、筆者の検証によってUE5も利用可能です!ただし、ビルド用Visual studioはVS2019を推奨します(筆者はVS2022のビルドでエラーだらけになった)。
GameLiftサーバーSDKから、GameLift Managed Servers SDKをダウンロードします。
- CMDでダウンロード先のフォルダに移動して、以下のコマンドでビルドを実施します。
mkdir out cd out cmake -G "Visual Studio 16 2019" -A x64 -DBUILD_FOR_UNREAL=1 .. msbuild ALL_BUILD.vcxproj /p:Configuration=Release
※ビルドにあたり、VS2019のmsvc C++ツールのバージョンがVS2017と違うのが原因で、以下のエラーが発生します。
msvc initialization: parameter version inconsistent
本エラーは、GameLift-Cpp-ServerSDK-3.4.2\out\thirdparty\boost配下のproject-config.jamにmsvcのバージョンを指定することで解決できます。
using msvc : 14.0 ;
- 無事にビルドが終わりましたら、生成したDLLとLibファイル
out\prefix\bin\aws-cpp-sdk-gamelift-server.dll out\prefix\lib\aws-cpp-sdk-gamelift-server.lib
を、プラグインのフォルダ(以下はパス)に複製して、セットアップが完了となります。
GameLift-SDK-Release-4.0.2\GameLift-Unreal-plugin-3.4.0\GameLiftServerSDK\ThirdParty\GameLiftServerSDK\Win64
手順4.ゲームサーバーにGameLiftプラグインの組込み
UE5のプロジェクトルートフォルダの配下に「Plugins」フォルダを新規作成し、手順3でセットアップ完了したプラグインをそこに移動します
プロジェクトフォルダのGamelift_UE5.slnァイルをクリックし、VS2019を立ち上げて、プラグインをインポートします
- 以下のプラグイン定義をゲームの Gamelift_UE5.uproject ファイルに追加します
- 以下のプラグイン定義をゲームの Gamelift_UE5.uproject ファイルに追加します
{ "Name": "GameLiftServerSDK", "Enabled": true }
b. Gamelift_UE5.Build.csファイルにプラグイン名「GameLiftServerSDK」をゲームリストに依存関係として追加します
c. 以下のGameLift を使用して Unreal Engine ゲームサーバーを初期化するコードを「Gamelift_UE5GameMode.cpp」に追加します
#if WITH_GAMELIFT //Getting the module first. FGameLiftServerSDKModule* gameLiftSdkModule = &FModuleManager::LoadModuleChecked<FGameLiftServerSDKModule>(FName("GameLiftServerSDK")); //InitSDK establishes a local connection with GameLift's agent to enable communication. gameLiftSdkModule->InitSDK(); //Respond to new game session activation request. GameLift sends activation request //to the game server along with a game session object containing game properties //and other settings. Once the game server is ready to receive player connections, //invoke GameLiftServerAPI.ActivateGameSession() auto onGameSession = [=](Aws::GameLift::Server::Model::GameSession gameSession) { gameLiftSdkModule->ActivateGameSession(); }; FProcessParameters* params = new FProcessParameters(); params->OnStartGameSession.BindLambda(onGameSession); //OnProcessTerminate callback. GameLift invokes this before shutting down the instance //that is hosting this game server to give it time to gracefully shut down on its own. //In this example, we simply tell GameLift we are indeed going to shut down. params->OnTerminate.BindLambda([=](){gameLiftSdkModule->ProcessEnding();}); //HealthCheck callback. GameLift invokes this callback about every 60 seconds. By default, //GameLift API automatically responds 'true'. A game can optionally perform checks on //dependencies and such and report status based on this info. If no response is received //within 60 seconds, health status is recorded as 'false'. //In this example, we're always healthy! params->OnHealthCheck.BindLambda([](){return true; }); //Here, the game server tells GameLift what port it is listening on for incoming player //connections. In this example, the port is hardcoded for simplicity. Since active game //that are on the same instance must have unique ports, you may want to assign port values //from a range, such as: //const int32 port = FURL::UrlConfig.DefaultPort; //params->port; params->port = 7777; //Here, the game server tells GameLift what set of files to upload when the game session //ends. GameLift uploads everything specified here for the developers to fetch later. TArray<FString> logfiles; logfiles.Add(TEXT("aLogFile.txt")); params->logParameters = logfiles; //Call ProcessReady to tell GameLift this game server is ready to receive game sessions! gameLiftSdkModule->ProcessReady(*params); #endif
d.GameLiftServerSDKのヘッドフォルダ(Plugins\GameLiftServerSDK\Source\GameLiftServerSDK\Public)をビルドのincludeパスに追加します。
e. UE5プロジェクトをビルドします
3. UE5プロジェクトのルートフォルダに戻してGamelift_UE5.uprojectをクリックしてUnreal Editorを立ち上げます、「Edit」⇒「Plugins」をクリックして、GameLiftSDKプラグインにチェックが入っていることを確認します
手順5.ローカルでゲームのテスト及びGameLiftへのアップロード
ここまでは、UE5ゲームサーバーの開発とGameLiftSDKの組込みは全部完了しました。
GameLiftへゲームサーバーをプッシュする前に、一応ローカルで次の点を確認します。
- ゲームサーバーが Server SDK と正常に統合されるか
- ゲームクライアントは新しいゲームセッションのスタート、プレイヤーのゲームへの参加、ゲームセッションへのConnectができるか
確認完了後に、以下の手順でGameLiftへアップロードを実施する
CMDでGameLiftローカルのセットアップ
cd {gameliftSDKダウンロード先}\GameLiftLocal-1.0.5
java -jar GameLiftLocal.jar -p 9080
ゲームサーバーを起動します
- 手順2でパッケージ化したゲームサーバーフォルダに移動します
- ゲームサーバーのログを出力したいため、起動exeのショットカットを作成して、 リンク先の後ろに「-log」を追加します
- ショットカットをクリックして、ゲームサーバーを起動します
- UE5プロジェクトのルートフォルダに戻して、Gamelift_UE5.uprojectをクリックしてUnreal Editorを立ち上げます、 をクリックして、出た画面でプレイヤー数を2に設定して でクライアントを起動します
CMDでゲームセッションを作成します
AWS gamelift describe-game-sessions --endpoint-url http://localhost:9080 --fleet-id fleet-123
AWS gamelift create-game-session --endpoint-url http://localhost:9080 --maximum-player-session-count 2 --fleet-id fleet-1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
クライアントからゲームサーバーに接続してみます。
- クライアントで
**~**
キーを押して、コマンドラインが表示されます、そこにローカルホストIP(127.0.0.1)を入力すれば、上記作成したゲームルームに入ります
※下記の図ではメモリ不足に関するエラーが発生していますが、検証に影響はないため無視して進めます。
- 接続確認します ローカルの検証はできたので、ここからAWS側で必要なリソースを作成します。
- クライアントで
GameLift側で起動用スクリプト作成
- 手順2でパッケージ化したゲームサーバーフォルダに移動します
- その配下にinstall.batを配置します、以下は中身です。
Engine\Extras\Redist\en-us\UEPrereqSetup_x64.exe /install /quiet /norestart /log c:\game\UE5PrereqSetup.log
以下のawsコマンドでゲームサーバーをGameLiftへアップロードします ※AWSの基本的な知識(IAMアカウント作成、aws cliセットアップなど)の説明は割愛いたします。
- operating-system: ゲームサーバーの稼働OS(筆者はwindows2012を採用します)
- build-root: 手順2で作ったパッケージのパス
- name: GameLiftでの表示名
- build-version: バージョン定義
- region: AWSのリージョン名
aws gamelift upload-build \
--operating-system WINDOWS_2012 \
--build-root "E:\UnrealBuilds\WindowsServer" \
--name "gamelift-Unreal-engine" \
--build-version "0.01" \
--region ap-northeast-1
aws consoleにログインして、GameLiftに開いてアップロードしたゲームサーバーを確認します。
- ビルド数の隣に「フリートを作成する」をクリックしてGameLiftのFleetを作成します。
数十分ほど待つとフリートが完成します。こちらは以下マネジメントコンソールのページからも確認することができます。
ここまでで、GameLift側の構築は完了となります。
手順6. AWS CLIコマンドによるゲームセッション作成と接続
まずマルチプレイを始めるにあたって、プレイヤーが集合するためのルーム、つまりGameLiftのゲームセッションを作成する必要があります(以降、ゲームセッションとして記載します)。次に、ゲームに接続するプレイヤーは、ゲームルームの「IPアドレス」を指定し、ゲームに参加することができます。 本来であれば、冒頭のAWSアーキテクチャ図のように別途APIGatewayとlambdaを用意し、ユーザー認証を実施した上でGameLiftへ接続するなどセキュリティーを考慮する必要がありますが、今回は検証のためAWS CLIを用いたコマンドベースで接続します。
ゲームセッション作成
- 以下のコマンドを、手順5で作成したフリートのIDを取得し変数として設定してください(マネジメントコンソールのフリートの一覧ページから作成したフリート ID の確認が可能)
aws gamelift create-game-session --fleet-id fleet-5f14fed2-30d6-4314-9220-47a261a9e6ee --maximum-player-session-count 2
- aのコマンドを実行しフリートにゲームセッションを作成します。
- 以下のコマンドを、手順5で作成したフリートのIDを取得し変数として設定してください(マネジメントコンソールのフリートの一覧ページから作成したフリート ID の確認が可能)
ゲームクライアントの起動とゲームサーバーへの接続
- ローカル検証する時と同様に、Unreal Editorで をクリックして、出た画面でプレイヤー数を2に設定して でクライアントを起動します。
- クライアントで
**~**
キーを押して、コマンドラインが表示されます、そこに「open IPアドレス」と入力することでゲームサーバーへ接続できます。
うまく接続できない場合、まずは以下の点を確認してみてください。
- クライアント側OSやプロキシなどのネットワークの経路上で接続をブロックしている設定がないか確認する
- GameLiftのフリートではEC2 ポート設定が反映できたか確認する
終わりに
今回、UE5とGameLiftを利用し、オンラインマルチプレイゲームの構築する方法をご紹介しました。 冒頭で記載した通り、メタバースにおいてよりよい没入感を実現するため、高精細なリアルタイムレンダリングが必要でこの辺はUnrealEngineの強みだと思います。 また、メタバース上でユーザーは「SecondLife」として生活していく上、運営側は大規模大人数同時オンライン可能のサーバーサイドの構築は不可欠で、今後ゲームサーバー技術の活用は増えていくと思われます。 そのため、引き続きゲーム領域のサーバーサイド技術をウォッチしていきたいと思います。
現在ISIDはweb3領域のグループ横断組織を立ち上げ、Web3およびメタバース領域のR&Dを行っております(カテゴリー「3DCG」の記事はこちら)。
もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください!
私たちと同じチームで働いてくれる仲間を、是非お待ちしております!
ISID採用ページ(Web3/メタバース/AI)
参考
執筆:@chen.sun、レビュー:@wakamoto.ryosuke (Shodoで執筆されました)