Unite Tokyo 2019 AWS For Unity
概要
コードとアセットのビルドパイプラインの手間をへらす
AWS Step Functions
CloudFormationでパイプラインをテンプレート化
Unityの規約の範囲でクラウド化する (規約はGitHubで公開されている)
ビルドについて
EC2を利用してアセットバンドルとゲーム本体をビルド
CIサーバからビルドサーバへアセット、成果物はS3へ転送する
高性能サーバを使用するか、ビルドタスクの並列化をするか
アセットのビルドはコア数やメモリを増やしてもスピードは変わらないので、分散ビルドを検討する必要があり (マルチスレッド未対応)
ゲーム本体のビルド時間はスケールアップで削減可能
スピードアップは線形では無いので、最適なスペックを探す必要あり
C++コンパイラはマルチスレッドでのコンパイルが可能
プラットフォームごとに並列化可能 (Assetの依存関係に注意)
ゲームにおけるAWSの活用例
APIサーバとして利用
APIアクセス: Unity→ロードバランサ→APIサーバ→キャッシュ→DB
AssetBundle: CloudFront→S3)
FGOはAWSをAPIサーバで利用している
SDKでサーバなしで機能実装
ゲーム内の写真をS3にアップロード
Amazon Pollyを利用して音声合成
画像アップロードとサムネイル作成: Unity → S3 → AWS Lambda
ゲームサーバとして利用
APIサーバとゲームサーバは相互通信
API: 認証/ロビー/イベント/ステータス/ゲームモード/マッチングメイキング
ゲームサーバ: ゲームマップホスト/セッション管理/ゲームプレイ, マップ更新/データ同期/ユーザ機能/チート対策/ゲーム終了レポート
ゲームサーバの実装とマッチメイキングの実装が面倒臭い
Amazon GameLift を使うと, セッションベースのメルチプレイヤーゲーム専用のゲームサーバを提供
GameLiftでマッチメイキングとサーバ管理を利用
手間かかる作業は不要/低レイテンシ/ローコスト&ハイスケール/FlexMatchのカスタムマッチメイキング
リアルタイムサーバ: Unity → ゲームサーバ → GameLift
カスタムサーバ: Unity → ゲームサーバ(Unity) → GameLift
GameLift
Nodeベース
jsでゲームサーバの振る舞いを定義
TCP/UDP
通信量が少ないものが向いてる
SDKはC#サポート, 同期/非同期両対応
コードはS3にアップロードする
詳細は公式ドキュメント
サンプルゲーム
対戦機能のあるテトリス, 相手に邪魔ブロックを投げられる
サーバ準備とSDK導入
ServerScriptsをGameLiftにアップロード
サーバ数とスペックを決めて起動
AWS .NET SDK と Gamelift Realtime Client SDK をダウンロード
2018.1.x と .NET4.5以上
ロビー実装
GameLiftのSDKでルーム作成や参加, 検索を行うことが可能
ClientApp → GameServer → GameLift
UnityからGameLiftへでマッチング要求を行う
ゲーム準備
コネクションを作る, クライアントからOKを送信、サーバからゲーム開始をクライアントへ送信
コネクションの作成はSDKから可能, TCP/UDPの選択も出来る
コネクションを作ったらRealtimeServerとのみ通信する (RTMessageプロトコルを使用, Protobufを利用して送信)
人数がそろったらサーバからクライアントにゲーム開始を伝える
盤面の情報
ViewとLogicは分離させている
一行削除したら相手を邪魔する
サーバロジックを追加 (ロジックをバレたくない, チート対策, 定期的に更新する)
ゲームサーバ側で一行消したのを検知して、相手のクライアントに送信する
まとめ
GameLift SDK を利用するとセッションとマッチメイキングが出来るようになる
通信フレームが定義されているのでゲームロジックで専念可能
わずかなコストで数百万のプレイヤーにスケール可能
Tips
Realtime Server はローカルでのデバッグが出来ない (EC2でやる)
同時接続設定された場合、セッションのクローズはGameServer側スクリプトで管理しないとリソースが開放されないので、新規接続ができなくなる
GameLiftの通信エラーはDebug.LogExceptionよりもLogErrorのほうが見やすい (InnerExceptionにエラーの詳細がある)
サーバログはコンソールからDL可能, SSHで直接サーバに入って確認することも出来る
基本の通信はTCPだが、メッセージはUDPに設定
UDPが利用出来ない場合はTCPにフォールバックされる
ネットワークのコールバックはメインスレッドではないので、一部APIコールはメインスレッドに戻す必要アリ