GameMode、GameState、PlayerState。名前が似ているうえに役割の説明もどこか抽象的で、UEを学び始めると必ず一度は混乱する三兄弟です。
見分けるコツは、機能ではなく 「どこに存在して、誰に共有されるか」 で覚えることです。この軸さえ持てば、シングルプレイヤーでもマルチプレイヤーでも迷いません。この記事では、3クラスの役割分担と、スコア獲得時の情報の流れ、そしてC++でチームデスマッチの土台を組む方法を解説します。
この記事でわかること
- 3クラスの違いは 「存在場所」と「複製されるか」 で覚える
- GameMode =ルールブック、 GameState =スコアボード、 PlayerState =個人の成績表
- スコア獲得が全員の画面に届くまでの 情報フロー
- 実践:C++で チームデスマッチの土台 を組む(
Replicated+DOREPLIFETIME)
3クラスの比較:どこにいて、誰に共有されるか
まず全体像です。この表が本記事の地図になります。
| クラス | 存在場所 | 役割 | 複製 |
|---|---|---|---|
| GameMode | サーバーのみ | ゲームのルール定義・実行 | されない |
| GameState | サーバー+全クライアント | ゲーム全体の状態管理 | される |
| PlayerState | サーバー+全クライアント | 各プレイヤーの状態管理 | される |

最重要ポイントは GameModeがサーバーにしか存在しない ことです。勝利条件やスポーン位置といったルールをクライアント側で改変させないための設計で、クライアントが知るべき情報は、GameStateとPlayerStateを経由して同期(複製)されます。シングルプレイヤーでは自分のPCがサーバーを兼ねるため、この構造を意識せずに動きます。ただし、内部の仕組み自体は同じです。
GameMode:ルールブック
GameModeはゲームの ルールそのもの を定義するクラスです。「審判」や「ルールブック」と考えるとイメージしやすいでしょう。
- プレイヤーの参加・退出時の処理(
PostLogin/Logout) - Pawnのスポーン位置・タイミング・条件
- マッチの開始・終了条件、ゲームモード固有のルール(デスマッチ、CTFなど)
GameModeはプロジェクト設定のマップ&モード、レベルごとのWorld Settings、またはURL引数で指定でき、レベルごとに違うルールで動かせます。
AGameModeBase vs AGameMode
基底クラスは2つあり、新規プロジェクトのデフォルトは AGameModeBase です。
| クラス | 特徴 | 推奨用途 |
|---|---|---|
AGameModeBase | シンプルで軽量 | シングルプレイヤー、非マッチベースのゲーム |
AGameMode | マッチステートマシン搭載 | チームデスマッチ等のマッチベースのマルチプレイヤー |

AGameMode には、いわば「試合の進行表」にあたるステートマシンが組み込まれています。管理するのは6つのマッチステート(EnteringMap → WaitingToStart → InProgress → WaitingPostMatch → LeavingMap、異常時 Aborted)です。「全員が揃うまで待機」「試合後のリザルト画面」のような進行制御を自前で書かずに済みます。
GameState:スコアボード

GameStateは ゲーム全体の現在の状態 を管理し、全クライアントへ同期するクラスです。GameModeが「ルールブック」なら、GameStateは会場に掲げられた「スコアボード」や「タイ マー」です。
- ゲーム経過時間:
GetServerWorldTimeSeconds()(サーバー同期された正確な時間) - 接続プレイヤーの一覧:
PlayerArrayプロパティ - チームスコアなど、 特定のプレイヤーに紐付かない ゲーム全体の情報
「これは誰か1人のものか、全体のものか?」で仕分けます。全体のものだけがGameStateの担当です。個人のスコアや名前は、次のPlayerStateへ。
PlayerState:個人の成績表
PlayerStateは 個々のプレイヤーの状態 を管理するクラスです。全クライアントに複製されるので、「他のプレイヤーのスコアをランキングUIに表示する」といった用途にそのまま使えます。
- プレイヤー名:
GetPlayerName() - スコア:
GetScore()/SetScore() - Ping:
GetPingInMilliseconds() - プレイヤーID・ボット判定:
GetPlayerId()/IsABot()
GameStateの PlayerArray にはPlayerStateのインスタンスが入っています。つまり「スコアボード(GameState)には、全員分の成績表(PlayerState)が綴じ込まれている」という関係です。
