BLOGブログ

2020.11.18UE4UE/ Network

[UE4]OnlineBeaconで通信

執筆バージョン: Unreal Engine 4.25

今回はOnlineBeaconについてです。

OnlineBeaconとは?

UE4で提供されている、RPC・プロパティのリプリケーションはクライアント-サーバーモデルに基づいて作成されています。
ゲームに参加したプレイヤーがUE4のルールに則った方法でしか通信できないようになっています。
そのため、同じレベル、GameControllerでの環境にログインした状態でないとこの仕組を利用することができません。

ログインしてしまうと余計な処理(レベルのロード等)が行われるので、
できれば、別レベルにいる状態でサーバとの通信を行いたい場合は、別の方法で通信をする必要があります。

UE4は機能が豊富なので、独自にソケット通信を実装し通信が可能ですが、
この場合、通信量が多い場合の通信量の制御や通信の失敗時の再送信等を独自に実装しないといけません。

今回紹介するOnlineBeaconを使用すると、RPC・プロパティのリプリケーションの仕組みを使用でき、別レベルでの通信を行うことが可能になります。

必要なクラス

OnlineBeaconを利用した通信を行う場合以下のクラスを用意する必要があります。

  • AOnlineBeaconHost
  • AOnlineBeaconHostObject
  • AOnlineBeaconClient

AOnlineBeaconHost

クライアントマシンからのAOnlineBeaconClientの接続リクエストを受け付けます。
通信までの流れは以下のようになります。

  1. 接続リクエストを受け付ける
  2. 登録しているAOnlineBeaconHostObjectにAOnlineBeaconClientが対応しているか確認
  3. 対応しているAOnlineBeaconClientが見つかったらホストマシン環境に同じAOnlineBeaconClientを生成し、通信を行える状態にします。

独自に使用するポート番号の特殊な指定を変更を行う等、処理を加えたい場合はこのクラスをもとにして拡張する必要がありますが、
このクラスは通常では派生の必要はありません。

AOnlineBeaconHostObject

AOnlineBeaconClient クラスの定義をAOnlineBeaconHostに登録するため、このクラスでは以下の定義が必要になります。

  1. BoeaconTypeNameの定義
  2. SpawnするAOnlineBeaconClientクラスの定義

BeaconTypeName メンバー変数に格納されている値と、クライアントの GetBeaconType の戻り値が一致すると
AOnlineBeaconClientの組み合わせが完了し、ホストとクライアント環境に存在するAOnlineBeaconClient同士の通信が可能になります。

簡単に各クラスの関係を図に表すとこのようになります。

C++での実装

1. NetDriverの追加

OnlineBeaconを利用するためいには 新たにゲームとは別のNetDriverが必要です。
BeaconNetDriverをDefautlEngine.iniに以下の設定を追加して下さい。

2. ModuleRuleに”OnlineSubsystemUtils”を追加

OnlineBeaconのモジュールを使用するためにPublicDependencyModuleNamesにOnlineSubsystemUtilsを追加して下さい。

3. AOnlineBeaconClientを継承したC++クラスを用意

ホストとクライアントの通信の実装はAOnlineBeaconClientに記述します。
基本的にはUE4のRPCとプロパティのレプリケーションが使用できますので、以下のドキュメントを参考にしてください。
RPC について
https://docs.unrealengine.com/ja/Gameplay/Networking/Actors/RPCs/index.html
プロパティのレプリケーション
https://docs.unrealengine.com/ja/Gameplay/Networking/Actors/Properties/index.html

ブループリントでも実装は可能ですが、一工夫する必要があります。
後述しますが、TSubclassOfを利用してブループリントのクラスを取得してAOnlineBeaconHostObjectのClientBeaconActorClassとBeaconTypeNameを設定することで可能です。

4. AOnlineBeaconHostObjectを継承したC++クラスを作成

例 1 コンストラクタで渡す。(AOnlineBeaconClientがC++で作られている場合)
2で用意したAOnlineBeaconClientの派生クラスをAOnlineBeaconHostObjectのClientBeaconActorClassに渡す。

例 2 ブループリントクラスをClientBeaconActorClassに指定したい場合
別途関数を用意して2で用意したクラスを継承したブループリントクラスを用意し、
そのブループリントクラスのUClassとクラス名をAOnlineBeaconHostObjectを継承したクラスに渡します。

return BeaconHostObject;
}
// 失敗
return nullptr;
}

5. ホスト側はAOnlineBeaconHostを生成して、3で作成したAOnlineBeaconHostObjectを登録する。

デフォルトで接続のリクエストは停止しているので、PauseBeaconRequests関数で停止を解除して下さい。

if (OnlineBeaconHost && OnlineBeaconHost->InitHost())
{
OnlineBeaconHost->PauseBeaconRequests(false);
}
}
if (OnlineBeaconHost)
{
AMyOnlineBeaconHostObject* BeaconHostObject = GetWorld()->SpawnActor(AMyOnlineBeaconHostObject::StaticClass());
if (BeaconHostObject)
{
OnlineBeaconHost->RegisterHost(BeaconHostObject);
}
}

6. クライアント側は2で用意したAOnlineBeaconClientを継承したクラスを作成し、ホスト側へ接続を行う

接続先IP、ポートの指定・接続開始はInitClient関数を使用します。
AOnlineBeaconClientも同様に接続のリクエストが停止しているので、PauseBeaconRequests関数で停止を解除して下さい。

InitClient(JoinURL);
// 接続のリクエストの停止を解除
PauseBeaconRequests(false);
}

その他の設定方法

使用するポート番号の指定方法

DefaultEngine.iniファイルにListenPort変数を追加します。

その他のポート番号指定方法

以下の方法で変更することができます。

  • 起動引数に「-BeaconPort=ポート番号」を追加する。
  • AOnlineBeaconHostのListenPortをInitHost前に上書きする
    ※ゲームのポートをもとに使用するポート番号を決める場合に利用

タイムアウトの設定

デフォルトで5秒に設定されていますが、変更したい場合は
DefautlEngine.iniに以下の設定を行うことでタイムアウト時間を変更することができます。

  • BeaconConnectionInitialTimeout (初期化時のタイムアウト時間)
  • BeaconConnectionTimeout (通常時のタイムアウト時間)

最後に

OnlineBeaconのUE4のドキュメントを確認すると基本C++で実装を想定されているので、敷居がある部分もあります。
ですが、UE4の通信の機能を使いつつ、ちょっと特殊なことができるようになります。