前回の記事の続きです。
今回は、公式で用意されている、UnityにGameLiftを組み込んでる(カスタムサーバー使用)サンプルを動かしてみたいと思います。
↓こちらです。
https://github.com/aws-samples/amazon-gamelift-unity
正直言って色々と微妙なサンプルなんですが、これ以外サンプルは無いので贅沢は言えません。
前の記事でも書きましたが、AmazonはGameLift使わせる気あるんか?Playfabに行っちゃうぞゴラァ!とか思いますが、どうやらこれには事情があるっぽいです。
実は、GameLiftは元々、Amazon製ゲームエンジンのLumberYardの機能の一部でした。ですのでLumberYardとGameLiftの統合には力が入ってて、簡単に使えますが、残念ながらLumberYardはまだベータ版で完成度が低く、利用者が少ない状況です。
このままだとせっかくのGameLiftが使ってもらえないので、しぶしぶUnityやUE4もサポートした、というのが経緯のようです。
ですのでUnity対応がやる気ないのは、さもありなんと言ったところでしょう。
サンプルを動かす
バッチファイルでアプリを自動ビルド
さておき、サンプルのREADMEを見ながら実際にサンプルを動作させてみましょう。
サンプル動かすだけの事を、わざわざブログで説明する事あんの?と言うと、GameLiftは当然ながらAWSの操作がちょっと絡むので、ちょっとややこしいので、一応説明します。
まず大前提として、OSはWindowsを使う必要があります。どこにも説明されてないですが、そうなんです。
事前準備として、UnityとVisual Studio(2013か2017、2019でも行けるかも)が必要です。Unityはなにげにバージョンが指定されていますが、「このバージョンでテストした事があるよ」程度の話で、まあ他のバージョンでも動くと思います。
それと、AWSのCLIツールのインストールも必要です。(PowerShellとかからawsコマンドを叩けるようにするツール)
では、リポジトリをzipダウンロードまたはクローンします。
次に、クローンしたフォルダの中のBuildフォルダにPowerShellで入って、その中のbuild.batを叩きます。(PowerShellから叩かないと、直接batファイルを実行すると、終わり次第ウインドウが即閉じするので結果が成功したのか失敗したのか分かりません)
このバッチファイルを実行するだけで、アラ不思議。自動的にビルドされてクライアントアプリとサーバーアプリが出来上がってOutputフォルダの中に入ってます。
え、何じゃそりゃ?そりゃあ、自動ビルドで魔法みたいにアプリをビルドしてくれるのは嬉しいですが、でもそれじゃサンプルになんないでしょ!何が起きたのかサッパリ分かんないんだから!
まあ、一応バッチファイルの中身を見れば、どういう手順の処理が実行されたのか大体分かります。
1.どこからかAWSSDKのDLLをダウンロードする。
2.ServerSDKをビルドしてDLLを生成する。
3.GameLiftにサーバーを自動でデプロイするためのデプロイツールをビルドする
4.Unityをバッチモードで起動して、クライアントアプリをビルドする
5.同じく、サーバーアプリをビルドする
こんな感じです。
何か途中でエラーが出てコケる場合がありますが、その時はバッチファイルを何とかしていい感じに修正しましょう。(そんな無茶な)
ゲームサーバーをGameLiftにデプロイする
AWSでGameLiftを操作するためのIAMユーザーを作成します。すでにIAMユーザーを作成済みの場合はこの手順をスキップできます。IAMユーザーのポリシーでIAMとS3とGameLiftの権限を付けておく必要があります。
IAMユーザーを作成した時の画面でCSV形式の資格情報ファイルがダウンロードできるので、忘れずにダウンロードしておきます。
aws CLIを使用して、”deploy“という名前で名前付きプロファイルを生成します。
1 |
aws configure --profile = deploy |
プロファイルの生成時に、アクセスキーIDとシークレットアクセスキーの入力を求められるので、さっきダウンロードしたCSVの中を見て入力します。
プロファイルが生成されると、そのPCにIAMユーザーの”資格情報”がインストールされたことになります。
どこにインストールされたの?というと、C:\Users\ユーザー名\.awsというフォルダの中の、credentialsというファイルを見ると、資格情報が保存されてるのが確認できます。
プロファイルを作成したら、以下のコマンドで環境変数を設定して、一時的に自分のプロファイルを”deploy”プロファイルに切り替えます。
1 |
set AWS_PROFILE=deploy |
次は、Buildフォルダの中のdeploy.batを叩きます。引数で1.0みたいな数字を付けてください。付けないと怒られます。この数字はビルドとフリートのバージョン名となります。ちなみにもう一つの引数でビルド名&フリート名を設定できます。
1 |
./deploy.bat 1.0 |
このバッチファイルの実行に成功すると、内部でデプロイツールを使用して、サーバーアプリを勝手にGameLiftにアップしてくれます。
ちゃんとアップされたか確認するために、ブラウザからIAMユーザーのアカウントでAWSにログインしてGameLiftのダッシュボードを見てみましょう。
こんな感じでビルド、フリート、エイリアスがそれぞれ一つずつ作られてるはずです。無いよ!って人は右上のとこから選択中のリージョンがバージニア北部になってる事を確認して下さい。勝手にこのリージョンにアップされます。
さて、ここまで読まれた方は、「ビルド、フリート、エイリアスって何じゃ?」と思われてるでしょう。私もこの時なんのこっちゃ分かりませんでした。簡単に説明します。
まず、”ビルド”というのはゲームサーバーの事です。ビルドとして上がってるって事は、GameLiftにアップされてます。が、まだこれだけではEC2にはアップされてません。
”フリート”というのは実際のEC2インスタンスです。オートスケールされた、複数のEC2インスタンスが中に含まれてます。フリートがアクティブになってないと、ゲームクライアントからゲームサーバーにアクセスできません。
”エイリアス”というのはフリートへのリンクみたいなもんです。ゲームクライアントのプログラムからはエイリアスを指定してフリートへ接続します。なんで直接フリートを指定せずに、エイリアスを挟んでワンクッション置くのか?というと、エイリアスを挟むことで、ゲームクライアントのコードをわざわざ変更しなくてもアクセス先のフリートを差し替えられるようにできるからです。
ビルド、フリート、エイリアスがそれぞれ作成されてるのが確認出来たら、フリートの状態を確認してください。フリートの状態は「検証中」とか「アクティブ化中」だったりしますが、準備が終わると「アクティブ」になります。アクティブじゃないとクライアントから接続できないので、アクティブになるまで待ちます。数分でアクティブになります。
クライアントアプリを実行する
フリートがアクティブになれば、クライアントから接続できますが、クライアントを実行する前に、もう一つ手順が必要です。
PCに”demo-gamelift-unity“という名前のプロファイルの資格情報もインストールする必要があります。何故なら、サンプルコードでこのプロファイル名がベタ書きで指定されてるからです。
READMEではここの手順は意味不明な説明が書かれてますが、要するにこうすればいいという手順を書きます。
C:\Users\ユーザー名\.aws ってディレクトリを開いて、credentialsファイルを開きます。
1 2 3 |
[deploy] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
↑なんかこういう感じになってるので、これをコピーしてその下にペーストします。そんでプロファイル名の所を”demo-gamelift-unity”に書き換えればOKです。
1 2 3 4 5 6 |
[deploy] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY [demo-gamelift-unity] aws_access_key_id = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
ではクライアントアプリを実行してみましょう。Buildフォルダ内のrc.batを実行します。引数にエイリアスIDが必要なので、GameLiftダッシュボードのエイリアスのところでIDを確認してそれを使ってください。
1 |
./rc.bat --alias alias-0c67a845-bc6e-4885-a3f6-40f1d2268234 |
これでクライアントが起動します。
クライアントが起動すると、こういうなんか意味分からん画面になってます。
とりあえず確認して欲しいのは、一番上の文字のとこです。CLIENT | GAMELIFT | CONNECTEDって書いてますが、これは今クライアントモードで、繋ぐ先はGAMELIFTで、現在正常に接続中。という意味で、正常だとこうなります。
さて、正常に起動したのはいいですが、これってどういうゲーム?すげえつまんなそう。どうやって遊ぶの?私の時はそう思いました。
遊び方ですが、まずエンターキーを叩くとゲームが開始されます。
マーブルチョコみたいなのが9個並んでますが、これがテンキーの1~9に対応してます。上のスクショの例だと、黄色いチョコが2つありますよね?だから、テンキーの5と6を同時に押してからキーを離すと、2点です。は?青いチョコは4つあるので、3と4と8と9を押して離すと4点です。何じゃこりゃ。
いくらサンプルだからゲームの内容はどうでもいいとは言え、もうちょっとこう…おもしろげにしてくれないと、こちらもやる気が出ないでしょう。
それはさておき、このクライアントを起動したまま、さっきのクライアント起動コマンドをもう一度叩くと、2つめのクライアントが起動します。
盤面が同期してて、対戦相手のスコアも表示されるので、ちゃんとマルチプレイができてる事が確認できると思います。
サンプルの動作確認はこれで終わりです。READMEにはGAMELIFTモード以外にも、LOCALモードとかDISCONNECTモードとかあるよ!みたいな説明が書いてますが、どうでもいいのでここでは説明しません。
サンプルの構成はベストプラクティスじゃない
さて、ここまで試してみて、「これなんかおかしくね?」と思った人もいるかもしれません。
クライアントアプリを実行するには”demo-gamelift-unity”ってプロファイルの資格情報がPCにインストールされてる必要がありましたね。
じゃあ、これでゲーム作って配布しても、ユーザーのPCには資格情報が入ってないから実行できないんじゃね?
そうなんです。
実はこのサンプルは、このままの構成ではゲームに使う事ができません!開発者向けに、便宜上こういう構成にしてるだけで、本番のリリースされたゲームでは別の構成にする必要があります!なんてこった
そもそも、AWSSDKというのはIAMユーザで認証しないと使用できないものです。アクセスキーIDとシークレットアクセスキーをソースコードにべた書きすれば、配布して動く形にできるようですが、いずれにせよゲームクライアントから直接GameLiftサービスを叩くのはベストプラクティスではありません。
READMEにもこういう風に注意書きがされてます。
これ、何を言ってるか分かりますか?私は最初サーパリ分かりませんでした。
つまるところ、AWSのAPI Gateway、Lambda、Cognitoと連携させるのがベストプラクティスだよって事です。
クライアントから直でGameLiftサービスを叩かなくていいように、CreateGameSession()とかCreatePlayerSession()とかのメソッドをそれぞれAPI Gatewayを使ってREST API化します。ゲームクライアントからはそのREST APIを叩きます。
というかこうしないと、どっちみちAWS SDKはdllだからスマホのクライアントアプリから実行できないですよね。
そのREST APIの中身はLambdaで実装します。まあ単に内部でCreateGameSession()とかのメソッド叩いて結果を返すだけです。
単にREST APIにするだけだと、誰でも叩けるようになってマズいので、Cognitoを使って認証されたクライアントからのみAPI呼び出しを受け付けるようにします。
残念ながら私はこの辺りの事まではまだやれてないので、またいずれ理解出来たら別途記事を書きたいと思います。
サンプルコードの中身を見てみよう
サンプルは実行できたものの、みなさんこれでGameLiftの組み込み方が理解できましたか?私はサッパリ分かりませんでした。
何しろ全部自動化されちゃってたので、中身がどういう構造になってたのかまったく分かりません。このサンプル、こういう所が良くないですね。
とにかく、Unityで手動でプロジェクトを開いてみましょう。
プロジェクトの中はこんな構成になってます。
シーンは1つだけ、スクリプトは3つだけで、シンプルな構成ですね。
Pluginsフォルダには色々なDLLが入ってます。AWSSDKとServerSDKのDLLです。自前のプロジェクトにGameLiftを統合する時は、これをコピーすればいいでしょう。
シーンファイルを開くと、さっき実行したサンプルと同じ画面です。
ただし、実行ボタンを押す前に、プレイヤーセッティングのScripting Define Symbolsの設定を確認しましょう。
ソースを見ると分かりますが、”SERVER“という定義がある場合は、サーバー側のコードが有効になります。”CLIENT“という定義がある場合は、クライアント側が有効になります。
ですので、クライアントの実行を試したい時は、ここで”CLIENT”を定義しておきます。
そして、実行ボタンを押すとクライアントが起動しますが、このままだとGameLiftで接続できなくて、LOCALモードで起動してしまいます。
コードでベタ書きされてるエイリアスIDを自分のものに書き直す必要があります。GameLift.csの365行目です。
1 2 3 4 |
// default alias - command line overrides, use --alias alias-0c67a845-bc6e-4885-a3f6-40f1d2268234 // or change the default below and rebuild the client (case sensitive command line) // buildconfig Client public string aliasId = "alias-0c67a845-bc6e-4885-a3f6-40f1d2268234"; |
あらためて実行するとGameLiftに正常に接続できます。
動作確認出来たところで、ソースを見ていきましょう。
まず、Credentials.csですが、これは資格情報の操作関係のコードで、まああんま気にしなくていいでしょう。
次に、GameLift.csです。これがGameLift統合の中核のコードです。
ソースの中に3つのクラスが定義されてます。GameLiftクラスはMonobehaviourで、シーンに置かれています。
“CLIENT”が定義されてる場合は、GameLiftClientクラスが有効化されて、GameLiftクラスから使用されます。同じく”SERVER”が定義されてる場合は、GameLiftServerクラスが有効化して、GameLiftクラスから使用されます。
ではGameLiftClientクラスを見てみましょう。
このクラスの役割は、AWSSDKを直接叩いて、GameLiftサービスとやり取りしてゲームセッションやプレイヤーセッションを生成する事です。
このクラスで重要なのは、GetConnectionInfoメソッドです。この中で諸々をやって、最終的には返り値としてサーバーのIPアドレス、ポート番号、プレイヤーセッションIDを返してくれます。
サーバーのIPとポートで接続するのはUNETでもMirrorでもMLAPIでも同じなので、このクラスの処理はどのネットワークライブラリでも使い回せます。
ただし、先ほども説明した通り、直接AWSSDKを叩くのはベストプラクティスでは無いので、最終的にはREST APIを叩く形に置き換わるハズです。
ちなみに、サーバーの部屋当たりの最大人数は、CreateGameSession()の中で設定します。486行目です。
1 |
cgsreq.MaximumPlayerSessionCount = 4; |
また、もしフリートのリージョンを変更している場合は、CreateGameLiftClient()の中で設定します。372行目です。
1 |
config.RegionEndpoint = Amazon.RegionEndpoint.USEast1; |
次に、GameLiftServerクラスを見てみましょう。Scripting Define Symbolsで”SERVER”定義に切り替えるとコードが見やすくなります。
このクラスの役割は、ServerSDKを叩いて、ゲームサーバーとGameLift間のやり取りを行います。
重要なのはProcessReadyメソッドです。この中でProcessParametersを生成してGameLiftサービスに渡してます。
ProcessParametersでは、ゲームセッションを開始した時のコールバック処理や、サーバをシャットダウンする時の処理、ゲームサーバーの状態を通知する処理、通信するポート番号の設定、ログ出力設定などを設定します。
そして、最後のソース、GameLogic.csですが、これはゲームの実装が書かれてます。あんま面白く無いゲームですし、特に重要な所ではないです。
手動でアプリをビルドする
一応手動でビルドする方法も書いておきます。
クライアントアプリをビルドするには、Scripting Define Symbolsで”CLIENT”を定義した状態で、普通にビルドすればOKです。
サーバーアプリをビルドするには、同じくScripting Define Symbolsで”SERVER”を定義した状態で、ビルドセッティングでServer Buildにもチェックを入れます。あとTarget Platformも普通はLinuxを選びます。(まあGameLiftではWindowsのEC2インスタンスも使えるのでその時はWindowsです) それでビルドすればOKです。
それで、手動でビルドをGameLiftにアップする方法は?それは次回の記事で書きます。
GameLiftLocal?
READMEでは、GameLiftLocalというものの使い方が書かれてます。GameLiftLocalを使うとイチイチゲームサーバーをGameLiftにアップしなくてもサーバーの動作をチェックできるようです。
素晴らしそうですね!
GameLiftLocalを使って、ローカルでゲームサーバー側のテスト方法は書かれてます。しかし、肝心のクライアント側のマルチプレイをテストする方法が書いてません。「TODO」って書かれてて、実際の内容が書かれないまま放置されてます。だから、どうやるか分かりません。
イチイチゲームサーバーをアップしないで動作テストできると便利そうなので、誰か方法をご存じの方はむしろ教えてください。
つづく
今回の記事では、公式のUnity+GameLiftサンプルの説明を行いました。私は最初サンプル見た時マジに意味不明でしたが、これを読めば多少理解しやすくなるかもしれません。
このサンプル、アプリのビルドもGameLiftへのアップロードも全部自動化されてて、たしかに上級者には便利でしょうけど、初心者にとってはまったく内容が理解できないので参考にならなくて良くないですよね。
次回の記事では、実際にMLAPIアプリにGameLiftを統合してみたものを用意して、それについて解説してみたいと思います。