関連ブログ
- [UE4][UE5]開発環境の容量を少しでも減らす 2024.08.14UE
- [UE5] PushModel型のReplicationを使い、ネットワーク最適化を図る 2024.05.29UE
- [UE5]マテリアルでメッシュをスケールする方法 2024.01.17UE
CATEGORY
2020.11.18UE4UE/ Network
執筆バージョン: Unreal Engine 4.25 |
今回はOnlineBeaconについてです。
UE4で提供されている、RPC・プロパティのリプリケーションはクライアント-サーバーモデルに基づいて作成されています。
ゲームに参加したプレイヤーがUE4のルールに則った方法でしか通信できないようになっています。
そのため、同じレベル、GameControllerでの環境にログインした状態でないとこの仕組を利用することができません。
ログインしてしまうと余計な処理(レベルのロード等)が行われるので、
できれば、別レベルにいる状態でサーバとの通信を行いたい場合は、別の方法で通信をする必要があります。
UE4は機能が豊富なので、独自にソケット通信を実装し通信が可能ですが、
この場合、通信量が多い場合の通信量の制御や通信の失敗時の再送信等を独自に実装しないといけません。
今回紹介するOnlineBeaconを使用すると、RPC・プロパティのリプリケーションの仕組みを使用でき、別レベルでの通信を行うことが可能になります。
OnlineBeaconを利用した通信を行う場合以下のクラスを用意する必要があります。
クライアントマシンからのAOnlineBeaconClientの接続リクエストを受け付けます。
通信までの流れは以下のようになります。
独自に使用するポート番号の特殊な指定を変更を行う等、処理を加えたい場合はこのクラスをもとにして拡張する必要がありますが、
このクラスは通常では派生の必要はありません。
AOnlineBeaconClient クラスの定義をAOnlineBeaconHostに登録するため、このクラスでは以下の定義が必要になります。
BeaconTypeName メンバー変数に格納されている値と、クライアントの GetBeaconType の戻り値が一致すると
AOnlineBeaconClientの組み合わせが完了し、ホストとクライアント環境に存在するAOnlineBeaconClient同士の通信が可能になります。
簡単に各クラスの関係を図に表すとこのようになります。
OnlineBeaconを利用するためいには 新たにゲームとは別のNetDriverが必要です。
BeaconNetDriverをDefautlEngine.iniに以下の設定を追加して下さい。
1 2 |
[/Script/Engine.Engine] +NetDriverDefinitions=(DefName="BeaconNetDriver",DriverClassName="/Script/OnlineSubsystemUtils.IpNetDriver",DriverClassNameFallback="/Script/OnlineSubsystemUtils.IpNetDriver") |
OnlineBeaconのモジュールを使用するためにPublicDependencyModuleNamesにOnlineSubsystemUtilsを追加して下さい。
ホストとクライアントの通信の実装は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を設定することで可能です。
例 1 コンストラクタで渡す。(AOnlineBeaconClientがC++で作られている場合)
2で用意したAOnlineBeaconClientの派生クラスをAOnlineBeaconHostObjectのClientBeaconActorClassに渡す。
1 2 3 4 5 6 |
AMyOnlineBeaconHostObject::AMyOnlineBeaconHostObject(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { ClientBeaconActorClass = AMyOnlineBeaconClient::StaticClass(); BeaconTypeName = AMyOnlineBeaconClient::StaticClass()->GetName(); } |
例 2 ブループリントクラスをClientBeaconActorClassに指定したい場合
別途関数を用意して2で用意したクラスを継承したブループリントクラスを用意し、
そのブループリントクラスのUClassとクラス名をAOnlineBeaconHostObjectを継承したクラスに渡します。
1 2 3 4 5 6 7 |
AMyOnlineBeaconHostObject* AMyOnlineBeaconHostObject::CreateOnlineBeaconHostObject(UWorld* World, TSubclassOf OnlineBeaconClientClass) { AMyOnlineBeaconHostObject* BeaconHostObject = World->SpawnActor(AMyOnlineBeaconHostObject::StaticClass()); if (BeaconHostObject) { BeaconHostObject->ClientBeaconActorClass = OnlineBeaconClientClass; BeaconHostObject->BeaconTypeName = OnlineBeaconClientClass->GetName(); |
return BeaconHostObject;
}
// 失敗
return nullptr;
}
デフォルトで接続のリクエストは停止しているので、PauseBeaconRequests関数で停止を解除して下さい。
1 2 3 4 |
// AOnlineBeaconHostはワールドに1つだけでOKなので、GameModeかPlayerController等にプロパティとして保持して下さい。 if (OnlineBeaconHost == nullptr) { OnlineBeaconHost = GetWorld()->SpawnActor(AOnlineBeaconHost::StaticClass()); |
if (OnlineBeaconHost && OnlineBeaconHost->InitHost())
{
OnlineBeaconHost->PauseBeaconRequests(false);
}
}
if (OnlineBeaconHost)
{
AMyOnlineBeaconHostObject* BeaconHostObject = GetWorld()->SpawnActor(AMyOnlineBeaconHostObject::StaticClass());
if (BeaconHostObject)
{
OnlineBeaconHost->RegisterHost(BeaconHostObject);
}
}
接続先IP、ポートの指定・接続開始はInitClient関数を使用します。
AOnlineBeaconClientも同様に接続のリクエストが停止しているので、PauseBeaconRequests関数で停止を解除して下さい。
1 2 3 4 5 6 7 |
void AMyOnlineBeaconClient::JoinBeacon(FString HostName, int32 Port) { FURL JoinURL; // 接続IPアドレス JoinURL.Host = HostName; // 使用するポート番号 JoinURL.Port = Port; |
InitClient(JoinURL);
// 接続のリクエストの停止を解除
PauseBeaconRequests(false);
}
DefaultEngine.iniファイルにListenPort変数を追加します。
1 2 |
[/Script/OnlineSubsystemUtils.OnlineBeaconHost] ListenPort=15000 |
以下の方法で変更することができます。
デフォルトで5秒に設定されていますが、変更したい場合は
DefautlEngine.iniに以下の設定を行うことでタイムアウト時間を変更することができます。
1 2 3 |
[/Script/OnlineSubsystemUtils.OnlineBeacon] BeaconConnectionInitialTimeout=60.0 BeaconConnectionTimeout=45.0 |
OnlineBeaconのUE4のドキュメントを確認すると基本C++で実装を想定されているので、敷居がある部分もあります。
ですが、UE4の通信の機能を使いつつ、ちょっと特殊なことができるようになります。