Let's Enjoy Unreal Engine

Unreal Engineを使って遊んでみましょう

UE4 ネットワークマルチプレイヤーゲームを作る時の役割について

ここ最近はUE4でネットワークを使ったマルチプレイヤーゲームを作る機会が多くなってきました。UE4はエンジン自体が最初からネットワークマルチプレイヤーを幅広くサポートしています。しかし、実際に制作を行うためにはエンジン独特のノウハウが必要で、これらを解説している情報というのは少ないというのが現状です。

そこで今回はUE4でネットワークマルチプレイヤーゲームを作るための設計やクラスごとの役割についてを解説したいと思います。UE4のネットワーク周りについてのドキュメントは以下のページにありますのでこちらも参考にしてください。

docs.unrealengine.com

またUE4でネットワークを扱う際に非常に重要な部分となる所有権とRPCについて、ヒストリアさんのブログ記事が非常に参考になるので、こちらもどうぞ。

historia.co.jp

今回の記事はListenサーバー、Dedicatedサーバー、どちらを使ったとしても考え方そのものは同じです。Listenサーバーの場合は、クライアント側の処理も含めてサーバーが行う必要があるということに気をつけましょう。

それではメインの解説をしていきます。

ゲームプレイフレームワークの役割

UE4にはゲームプレイフレームワークという仕組みが最初から備わっており、これはネットワークゲームを作る場合でなくても有用な仕組みですが、本質的にはネットワークゲームを作るために用意された仕組みです。これらに用意されたクラスで特に重要なのが以下のクラス達です。

  1. Game Mode
  2. Game State
  3. Game Instance
  4. Pawn
  5. Player Controller
  6. Player State
  7. UMG Widget & HUD

UE4のネットワークは『Client-Serverモデル』というアーキテクチャーを採用しています。これはつまり、サーバーが全てのゲーム情報を管理し、クライアントは受け取った結果を表示するだけということになります。

さて、問題はこれらのクラスがクライアントとサーバー上でどのようになっているのでしょうか?全ての情報はクライアントにもある?むしろサーバーにしかないの?という疑問点がでてきますが、まずは整理してみましょう。

  • サーバーのみ → 名前の通りサーバーのみに存在するもの。
  • サーバーとクライアント → サーバー上と全てのクライアント上に存在するもの。
  • サーバーと所有クライアントのみ → サーバー上とそれを所有するクライアントでのみ存在するもの。
  • 所有クライアントのみ → サーバーには存在せず、それを所有するクライアントでのみ存在するもの。

上記4タイプに区別されることになります。では上記クラスをそれぞれに割り当ててみたものを画像にしました。

f:id:alwei:20210223215126j:plain

これでどのクラスがクライアントとサーバーでどこに存在するかがわかりやすくなりました。これらのゲームプレイフレームワークではそれぞれのクラスに明確に役割が割り当てられており、それぞれを使い分けて使う必要があります。では次は個別にどういう役割があるかをみていきましょう。

Game Mode

まずはGame Modeです。このクラスを使ったことがある人は非常に多いかと思いますが、ネットワークにおけるGame Modeはサーバー上にしか存在しないことになっています。ここはサーバーのみしか知る必要のない情報を管理する場所です。主にゲームのルールやサーバー主導のゲーム進行を管理することとなります。

Game Modeは各クライアントがログインやログアウトした際に、それぞれOnPostLoginやOnLogoutイベントを使って、ログイン後などの処理を行うことが可能な唯一の存在です。実質的にはクライアントを唯一初期化することが可能で、OnPostLoginでPlayer Controllerを取得することが可能なのでこれをGame Modeに保持させておくことで個別のクライアント情報をサーバー管理することが出来るようになります。

ログイン後にクライアントはPlayer Controllerを介して、Widgetなどの初期化も行うことができます。

Game State

Game Stateは名前の通りゲームの状態を管理してくれるものですが、Game Stateはサーバーとクライアント全体で1つのものを共有しており、クライアントは一度サーバー上にRPCを送信することでレプリケーションされた変数は全てのクライアントで共有されることとなります。

Game Stateはゲームログイン後にゲームの進行が開始した時に、その進行状況や全体スコア管理などを行う時に最も的しており、グローバルな存在でありながらサーバーとクライアント両方で処理が可能というメリットもあります。

Game Instance

Game Instanceはゲーム中、永続的な存在でサーバーと全てのクライアント上に存在します。ただし、これは他のクラスと違ってインスタンスを共有しません。つまり各ローカルでのみ保持したい情報を管理する際に向いています。

具体的に言えばログイン時に使うアカウント情報やゲーム起動後にずっと記録しておきたい情報などです。また、Game Instanceはログイン前やログアウト後の情報を管理することが可能な唯一な存在のため、何か問題が起きた際にも非常に重要な役割を持ちます。

ネットワークが切断された場合もその情報をトラッキングできるのがGame Instanceのみとなるため、ネットワークエラーハンドリングを行いたい場合にはこのGame Instanceを使っていくことになるでしょう。

Pawn

Pawnはゲーム中のプレイキャラクターのことで、実際にはPawnを継承したCharacterクラスを使っていることも多いと思います。PawnはPlayer ControllerとPlayer Stateと強い関連性を持っており、ゲームにログインした後にPlayer ControllerはスポーンしたPawnに対してPossessを使って、キャラクターに乗り移ることになります。

Pawnはゲーム中に別のPawnへと切り替えることによって別キャラクターを操作することも可能です。またはキャラが死亡、または破壊された際にリスポーンすることによって改めてキャラクターを変更することも可能です。

Pawnは実質的にゲーム中のキャラクターそのものなのでサーバーと全てのクライアントに存在することになりますが、それの所有権や情報はあくまでもPlayer Controllerが管理していることを意識しておく必要があります。途中でキャラが切り替わるとその情報も消滅してしまいます。

Player Controller

Player Controllerはクライアントにとって最も重要な存在です。サーバー上には当然存在しますが、各クライアントには個別のPlayer Controllerしか存在しません。つまりクライアントAとクライアントBではお互いのPlayer Controllerの情報は共有されません。

ゲームへログイン後、クライアントが自分を判別することができる唯一の存在のため、Player Controllerがクライアント内での最大の権限を持つことになります。途中でPawnが切り替わるとそのPawnの情報は失われますが、Player Controllerの情報は消滅しません。

また、UMG WidgetなどのUIは各クライアントのみに存在する情報なため、基本的にPlayer Controllerが管理する必要があります。サーバーとやりとりする場合においてもこのPlayer ControllerからRPCを送信することになりますので、クライアント側を作成する際には長い間お世話になる存在です。

Player State

Player Stateはプレイヤーの状態を管理し、Game Stateとは違い各クライアント毎に1つずつ作成されます。Player Controllerでもある程度代用可能ですが、Player Controllerとは違い、サーバーと全てのクライアント上に存在するので共有が可能です。

Game Stateがゲームの状態を管理するものであるならこちらはプレイヤー固有の情報を管理する存在です。例えばライフポイントや自分自身のスコアなど。Player StateはPawnが破壊やリスポーンしても存在し続けるので、複数マッチのゲームでプレイヤーの情報を管理したい場合に利用するのに向いています。

UMG Widget & HUD

最後にUMG WidgetとHUDについてです。これはUIとしてゲーム中に存在しますが、見た目が各クライアント固有の情報となるため、サーバー上には存在しません。各クライアントがPlayer ControllerやPlayer Stateなどの情報から見た目に関する部分を作成する必要があります。

また作成は必ずサーバー側で各クライアントに対して、Player ControllerからRPCの所有クライアントで実行(Run on Owning Client)でクライアント個別に対して行う必要があり、少々ややこしい面もあります。各クライアントのみにある情報なので、管理が難しい部分とも言えます。

基本方針について

最後にまとめとなりますが、基本的な方針についてです。UE4のネットワークマルチプレイヤーゲームはこれらのクラスを明確に使い分けて使うことで、非常に柔軟なネットワークゲーム作成が可能です。その上で基本方針をまとめてみますと…

  1. Game Modeにはサーバー固有情報とログイン、ログアウト周りのフローを管理させ、余計な機能はなるべく持たせない
  2. Game Stateでゲームの進行を管理させ、ゲーム中のクライアントからの情報もここに集約させるようにする
  3. Game Instanceはアカウント情報やゲームログイン前やログアウト後に必要な情報を持たせて、ネットワーク切断などのエラーハンドリングも行う
  4. Player ControllerはクライアントがサーバーへRPCを送信する際のハブとなってもらい、Pawn、Player State 、UMG Widgetなどを制御するベースになってもらう
  5. Player Controller以外にPossess後のPawnとPlayer StateからでもサーバーへのRPC送信は可能だが、個々の役割がより難しくなるため控えるようにする

以上が基本方針となります。ネットワークゲームを作るのは色々とややこしいですが、これらを理解して設計を行えばかなりスムーズにネットワークゲームを作ることができるのは間違いありません。


最後にこれらの情報について詳しく書かれたドキュメントが公式にもありますので紹介しておきます。
docs.unrealengine.com