SlideShare a Scribd company logo
© historia Inc. #UE4DD
Multiplayer Online Deep Dive
- Traveling -
historia Inc.
原 龍
© historia Inc. #UE4DD
Traveling ?
 Listen Server を開始したり、Server に接続したり、
各プレイヤーの接続やレベル移動周りの話です
 今回は OnlineSubsystem の Session 等は解説しません
© historia Inc. #UE4DD
Standalone
Server Map A で Listen 開始Map A
Map X
Listen Server としてレベルを開始する → Listen 付き OpenLevel
© historia Inc. #UE4DD
Standalone
Server Map A
Client として接続リクエスト
Client として Server に接続する → ClientTravel
接続させて
Map X
© historia Inc. #UE4DD
Client
Server Map A
Map A
Client として Server に接続する → ClientTravel
いいよ
読み込むレベルを通知
© historia Inc. #UE4DD
Client
Server Map B
Map A
Server がレベル移動する → ServerTravel
移動します
移動先のレベルを通知
© historia Inc. #UE4DD
Client
Server Map B
Map B
Server がレベル移動する → ServerTravel
移動しました
© historia Inc. #UE4DD
Listen Server としてレベルを開始する
© historia Inc. #UE4DD
Standalone
Server Map A で Listen 開始Map A
Map X
Listen Server としてレベルを開始する → Listen 付き OpenLevel
© historia Inc. #UE4DD
Listen Server としてレベルを開始する
C++
/** Start Server */
UGameplayStatics::OpenLevel(GetWorld(), “LevelName", true, "listen");
© historia Inc. #UE4DD
Listen Server としてレベルを開始する
Blueprint
© historia Inc. #UE4DD
Server
UGameplayStatics::OpenLevel Listen Server 開始リクエスト
UEngine::Browse
UWorld::Listen
UEngine::CreateNamedNetDriver
UNetDriver::InitListen
Listen Server 開始
NetDriver 作成
© historia Inc. #UE4DD
Client として Server に接続する
© historia Inc. #UE4DD
Standalone
Server Map A
Client として Server に接続する → ClientTravel
接続させて
Map X Client
Server Map A
Map A
いいよ
© historia Inc. #UE4DD
Client として Server に接続する
C++
APlayerController* PlayerController =
UGameplayStatics::GetPlayerController(GetWorld(), 0);
/** Start Client */
PlayerController->ClientTravel(
“XXX.XXX.XXX.XXX”, // IP Address
ETravelType::TRAVEL_Absolute, // トラベルタイプ
false); // シームレストラベル有効フラグ
© historia Inc. #UE4DD
Client として Server に接続する
Blueprint
© historia Inc. #UE4DD
UPendingNetGame::InitNetDriver
UEngine::CreateNamedNetDriver
UNetDriver::InitConnect
APlayerController::ClientTravel Server 接続リクエスト
NetDriver 作成
UEngine::Browse
Client
接続開始
© historia Inc. #UE4DD
FNetControlMessage<NMT_Hello>::Send
UNetDriver::InitConnect 接続開始
UConnection::CreateChannel ※CHTYPE_Control
Client
Control Channel 作成
Server へ Hello メッセージ送信
© historia Inc. #UE4DD
UPendingNetGame ?
 Control Channel で Server に Hello メッセージして待っている間、
UPendingNetGame オブジェクトが Server からの返答待ち及び、
Server が Closed になっていないかどうかの監視を行う
© historia Inc. #UE4DD
Control Channel ?
 C/S 間の接続の制御に利用されるチャンネル
 UConnection 生成時に一つ生成される
© historia Inc. #UE4DD
ServerClient
Hello
ServerClient
Challenge
ServerClient
Login
ServerClient
Welcome
1 2
3 4
© historia Inc. #UE4DD
Server
UWorld::NotifyControlMessage Hello メッセージ受信
FNetworkVersion::IsNetworkCompatible
FNetControlMessage<NMT_Challenge>::Send Client へ Challenge メッセージ送信
Network Version チェック
© historia Inc. #UE4DD
Network Version ?
 C/S 間でアプリケーションの Network Version の照合を行うことができる
 Server で Hello 受信時にバージョンチェックを行い、問題があれば
Upgrade メッセージを Client に送信し、Client ではエラーとして処理する
Server
ver. 1.1
Client
ver. 1.0
Hello
Upgrade
更新して出直して来いこんにちは
© historia Inc. #UE4DD
Network Version ?
 デフォルトだとバージョン情報は下記を繋げた文字列のハッシュ値
– Game Name
– Project Version
– ENGINE_NET_VERSION
– Engine Network Protocol Version
– Game Network Protocol Version
© historia Inc. #UE4DD
Network Version を制御するには ?
 Game Network Protocol Version をアップデートに合わせて変更する
– FNetworkVersion::GameCompatibleNetworkProtocolVersion
 もしバージョン違いをある程度許容したい場合は下記をバインドして独自制御する
/** Called in GetLocalNetworkVersion if bound */
DECLARE_DELEGATE_RetVal( uint32, FGetLocalNetworkVersionOverride );
static FGetLocalNetworkVersionOverride GetLocalNetworkVersionOverride;
/** Called in IsNetworkCompatible if bound */
DECLARE_DELEGATE_RetVal_TwoParams( bool, FIsNetworkCompatibleOverride, uint32, uint32 );
static FIsNetworkCompatibleOverride IsNetworkCompatibleOverride;
FNetworkVersion
© historia Inc. #UE4DD
UPendingNetGame::NotifyControlMessage Challenge メッセージ受信
ULocalPlayer::GetPreferredUniqueNetId
FNetControlMessage<NMT_Login>::Send Server へ Login メッセージ送信
OnlineSubsystem から Net ID を取得
Client
© historia Inc. #UE4DD
Server
UWorld::NotifyControlMessage Login メッセージ受信
AGameModeBase::PreLogin
UWorld::WelcomPlayer
ログイン前処理
AGameModeBase::GameWelcomPlayer
FNetControlMessage<NMT_Welcome>::Send Client へ Welcome メッセージ
© historia Inc. #UE4DD
PreLogin でログイン許可判定
 AGameModeBase::PreLogin では ErrorMessage を返すことができる
 規定人数に達していたり、何らかの要因でログインさせたくない場合は
ErrorMessage に何らかの文字を入れることで、
Client には Control Channel から Failure メッセージが飛ぶ
ServerClient
Login
Failure
お前はダメログインしたい
© historia Inc. #UE4DD
UPendingNetGame::NotifyControlMessage Welcome メッセージ受信
Map 名を受け取る
UEngine::TickWorldTravel
UEngine::LoadMap Map 読み込み
Client
UPendingNetGame::LoadMapCompleted
FNetControlMessage<NMT_Join>::Send Server へ Join メッセージ送信
© historia Inc. #UE4DD
Server
UWorld::NotifyControlMessage Join メッセージ受信
UWorld::SpawnPlayActor PlayerController をスポーン
AGameModeBase::Login
AGameModeBase::PostLogin
ログイン受け入れ
© historia Inc. #UE4DD
ここまでの内容をまとめると
© historia Inc. #UE4DD
• AGameModeBase
• UNetDriver
• UNetDriver• UNetDriver
Client 1
Server
Client 2
• UNetConnection
• UControlChannel
Server / Client
• UNetConnection
• UControlChannel
Server / Client
© historia Inc. #UE4DD
Server がレベル移動する
© historia Inc. #UE4DD
Client
Server Map B
Map A
Server がレベル移動する → ServerTravel
移動します
Client
Server Map B
Map B
移動しました
© historia Inc. #UE4DD
Server がレベル移動する
C++
/** Start ServerTravel */
GetWorld()->ServerTravel(“LevelName”, false);
© historia Inc. #UE4DD
Server がレベル移動する
Blueprint
© historia Inc. #UE4DD
Server
UWorld::ServerTravel ServerTravel 開始
AGameModeBase::CanServerTravel
AGameModeBase::ProcessServerTravel
ServerTravel 可否判定
AGameModeBase::ProcessClientTravel
NextURL 設定
(後に UEngine::Browse でレベル移動する)
APlayerController::ClientTravel
各 Client で ClientTravel を実行
(Run on Owning Client & Reliable)
© historia Inc. #UE4DD
APlayerController::ClientTravel Server 接続リクエスト
Client
以下、前述した ClientTravel の流れと同じ
Control Channel を介してログイン処理を行う
© historia Inc. #UE4DD
つまり、ServerTravel でレベル移動を行うと、
移動する度に Server へのログイン処理が実行される
© historia Inc. #UE4DD
接続を維持したままレベル移動を行いたい場合は?
→ SeamlessTravel を利用する
© historia Inc. #UE4DD
SeamlessTravel ?
 レベルをストリーミングで読み込み、Transition Map を経由しながら GameMode
等の Actor を引き継いだままレベル遷移する事で、オーバーヘッドを小さくできる
 非 Seamless な ServerTravel と違い、Client との接続は保持したまま
BeforeMap AfterMapTransition Map
© historia Inc. #UE4DD
SeamlessTravel を有効にする
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=GameMode)
uint32 bUseSeamlessTravel : 1;
AGameModeBase
© historia Inc. #UE4DD
Transition Map ?
 ワールドを保持したままレベル遷移するため、古いレベルがオンメモリのまま
新しいレベルが読み込まれる
 つまり瞬間的に二つのレベルが共存するため、メモリに優しくない
 そのため小さな Transition Map を間に挟むことで、古いレベルを解放してから
新しいレベルのロードが始まるように処理されている
© historia Inc. #UE4DD
Transition Map を設定する
© historia Inc. #UE4DD
Server
AGameModeBase::ProcessServerTravel
UWorld::SeamlessTravel
NextURL は 設定しない
(UEngine::Browse されない)
FSeamlessTravelHander::StartTravel SeamlessTravel 開始
FSeamlessTravelHander::LoadPackageAsync レベルストリーミング開始
© historia Inc. #UE4DD
FSeamlessTravelHander ?
 SeamlessTravel 時のシーケンス管理用オブジェクト
 TransitionMap を LoadAsync して完了待ちを行い、完了したら古いレベルを
PendingKill してから CollectGarbage する
 TransitionMap への移行が完了したら、新しいレベルへの移行シーケンスを開始する
© historia Inc. #UE4DD
Server
Client
SeamlessTravel
SeamlessTravel
ServerTravel
- PreClientTravel
ClientTravel
- PreClientTravel
Client / Reliable Server / Reliable
ServerNotifyLoadedWorld
NotifyLoadedWorld
PostSeamlessTravel
NotifyLoadedWorld
© historia Inc. #UE4DD
Server
Client
SeamlessTravel
SeamlessTravel
ServerTravel
- PreClientTravel
ClientTravel
- PreClientTravel
ServerNotifyLoadedWorld
NotifyLoadedWorld
PostSeamlessTravel
NotifyLoadedWorld
開始 / 終了のトリガー
Client / Reliable Server / Reliable
© historia Inc. #UE4DD
SeamlessTravel 時に引き継がれるアクターは?
 [Server] GameMode / GameState
 [Server] 有効な PlayerState を持つ全ての Controller
 [Server] 全ての PlayerController
 [Server / Client] 各 Server / Client が所持する PlayerController
© historia Inc. #UE4DD
ゲーム都合で引き継ぐアクターを追加したい場合は?
 下記関数をオーバーライドして ActorList に追加する
– AGameModeBase
 GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList)
– APlayerController
 GetSeamlessTravelActorList(bool bToEntry, TArray<class AActor*>& ActorList)
© historia Inc. #UE4DD
と、ドキュメントには記載があり、大体合ってるが…
© historia Inc. #UE4DD
SpawnPlayerController
新規に PlayerController を
スポーンして Swap している
© historia Inc. #UE4DD
PlayerController で引き継がれるプロパティは?
 Location, Rotation
 保持する PlayerState の全プロパティ(コピーされる)
 RemoteRole 等、Online 系のプロパティ
© historia Inc. #UE4DD
ゲーム都合で引き継ぐプロパティを追加したい場合は?
/** Called when a PlayerController is swapped to a new one during seamless travel */
UFUNCTION(BlueprintImplementableEvent, Category=Game, meta=(DisplayName="OnSwapPlayerControllers"))
void K2_OnSwapPlayerControllers(APlayerController* OldPC, APlayerController* NewPC);
AGameModeBase
イベント呼び出し時に
必要なものをコピーする
© historia Inc. #UE4DD
OnSwapPlayerControllers の注意点
 PlayerController が Local or Remote で Swap タイミングが異なる
– Local PlayerController は Swap -> BeginPlay の順番
– Remote PlayerController は BeginPlay -> Swap の順番
 Swap が呼び出されるのは Server のみ
© historia Inc. #UE4DD
SeamlessTravel をデバッグする
© historia Inc. #UE4DD
SeamlessTravel をデバッグする時の注意点
 PIE は現状だと非サポート
 デバッグするためには Standalone で起動する必要がある
– イテレーション速度の低下
– そもそもエディタからは複数プロセスで Standalone 起動はできない
 game オプション付きで起動するバッチファイルを作るのがオススメ
© historia Inc. #UE4DD
Visual Studio でデバッグする
 エディタもしくはバッチファイルから Standalone 起動した場合、
Visual Studio でデバッグしたいなら Attach to Process するしかない
 デバッグする度に、検索窓も無いプロセス一覧から特定のプロセスを探して
アタッチして…、というのは非常に面倒
© historia Inc. #UE4DD
UnrealVS を使ってコマンドラインに渡す引数を追加する
[ProjectName] [起動したいMap] –game [その他オプション]
と設定して Start Debugging すると、デバッグしながら起動できる
実行したコマンドラインオプションは履歴が残り、プルダウンで設定できるので便利
© historia Inc. #UE4DD
UnrealVS で楽にはなるが、それでも PIE 非対応は辛い…
// NOTE - This is a temp check while we work on a long term fix
// There are a few issues with seamless travel using single process PIE, so
we're disabling that for now while working on a fix
AGameModeBase::CanServerTravel
SeamlessTravel + PIE は現状だといくつかのバグを抱えていて、
将来的にこれは解決される見込みとのことなので、今後に期待
© historia Inc. #UE4DD
まとめ
 Server としてレベル移動する時、Client として Server に接続する
初回のレベル移動はブロッキングが発生する
 C/S 間接続のキモは UControlChannel で、メッセージタイプも多くないので
何がサポートされているのかを最初に眺めてみると良い
 SeamlessTravel はデバッグが辛いので早期改善を希望
© historia Inc. #UE4DD
まとめ
 色々困ったら下記クラスの実装を追うと良い
– UWorld
– AGameModeBase
– APlayerController
– UNetConnection
– UControlChannel
– FSeamlessTravelHandler
© historia Inc. #UE4DD
ご清聴ありがとうございました
historia Inc.
原 龍

More Related Content

PPTX
UE4 MultiPlayer Online Deep Dive: 実践編1 (Byking様ご講演) #UE4DD
PPTX
UE4 MultiPlayer Online Deep Dive 基礎編1 -Getting Started- (historia様ご講演) #UE4DD
PDF
Epic Online Services でできること
PDF
UE4でマルチプレイヤーゲームを作ろう
PDF
CEDEC2016: Unreal Engine 4 のレンダリングフロー総おさらい
PDF
UE4プログラマー勉強会 in 大阪 -エンジンの内部挙動について
PPTX
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)
UE4 MultiPlayer Online Deep Dive: 実践編1 (Byking様ご講演) #UE4DD
UE4 MultiPlayer Online Deep Dive 基礎編1 -Getting Started- (historia様ご講演) #UE4DD
Epic Online Services でできること
UE4でマルチプレイヤーゲームを作ろう
CEDEC2016: Unreal Engine 4 のレンダリングフロー総おさらい
UE4プログラマー勉強会 in 大阪 -エンジンの内部挙動について
[CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編)

What's hot (20)

PDF
そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 2 <Texture Streaming, メモリプロ...
PPTX
ゆるゆるUE4ネットワーク入門
PDF
UE4におけるエフェクトの基本戦略事例 後半
PDF
PDF
UE4のマテリアルを もっと楽しもう!~マテリアルでぐっと広がるリアルタイムCG表現の幅~
PPTX
UE4におけるLoadingとGCのProfilingと最適化手法
PDF
そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
PPTX
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
PDF
UE4 コリジョン検証 -HitとOverlapイベントが発生する条件について-
PDF
UE4 MultiPlayer Online Deep Dive 実践編2 (ソレイユ株式会社様ご講演) #UE4DD
PDF
UE4 アセットロード周り-アセット参照調査-
PPTX
[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法
PPTX
UE4のためのより良いゲーム設計を理解しよう!
PDF
第1回UE4勉強会 in 大阪 - エンジン改造ってどうなの?
PDF
UE4×Switchで60FPSの(ネットワーク)対戦アクションをなんとかして作る! | UNREAL FEST EXTREME 2020 WINTER
PDF
UE4におけるエフェクトの為のエンジン改造事例
PDF
猫でも分かるUE4.22から入ったSubsystem
PDF
UE5制作事例 “The Market of Light” ~Nanite/Lumenへの挑戦~
PPTX
最新UE4タイトルでのローカライズ事例 (UE4 Localization Deep Dive)
そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 2 <Texture Streaming, メモリプロ...
ゆるゆるUE4ネットワーク入門
UE4におけるエフェクトの基本戦略事例 後半
UE4のマテリアルを もっと楽しもう!~マテリアルでぐっと広がるリアルタイムCG表現の幅~
UE4におけるLoadingとGCのProfilingと最適化手法
そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
大規模タイトルにおけるエフェクトマテリアル運用 (SQEX大阪: 林武尊様) #UE4DD
UE4 コリジョン検証 -HitとOverlapイベントが発生する条件について-
UE4 MultiPlayer Online Deep Dive 実践編2 (ソレイユ株式会社様ご講演) #UE4DD
UE4 アセットロード周り-アセット参照調査-
[4.20版] UE4におけるLoadingとGCのProfilingと最適化手法
UE4のためのより良いゲーム設計を理解しよう!
第1回UE4勉強会 in 大阪 - エンジン改造ってどうなの?
UE4×Switchで60FPSの(ネットワーク)対戦アクションをなんとかして作る! | UNREAL FEST EXTREME 2020 WINTER
UE4におけるエフェクトの為のエンジン改造事例
猫でも分かるUE4.22から入ったSubsystem
UE5制作事例 “The Market of Light” ~Nanite/Lumenへの挑戦~
最新UE4タイトルでのローカライズ事例 (UE4 Localization Deep Dive)
Ad

Similar to UE4 MultiPlayer Online Deep Dive 基礎編2 -Traveling- (historia様ご講演) #ue4dd (20)

PDF
第20回 OpenStack勉強会 Neutron Deep Dive - DVR
PDF
OpenWrtによるサイト間IPsec接続
PDF
Opencontraildays2014dist 140514051248-phpapp01
PDF
Open contraildays2014
PDF
Deno の node 互換モードと ソケット
PDF
Serf / Consul 入門 ~仕事を楽しくしよう~
PDF
NGINX Ingress Controller on RedHat OpenShift.pdf
PDF
OpenStackネットワーキング管理者入門 - OpenStack最新情報セミナー 2014年8月
PDF
Lagopus + DockerのDPDK接続
PDF
Docker Machineを始めるには?
ODP
"Up" with vagrant and docker
PDF
Apache cloudstack4.0インストール
KEY
P2Pって何?
PDF
"Up" with vagrant and docker
PDF
Docker swarm mode 入門と ECS との比較
PPTX
20140826 it pro_expo_rev2
PDF
NGINX Back to Basic 2 Part 2 (Japanese Webinar)
PPTX
MSC2014_NetApp_Session
PDF
Juniper NetworkGuru Plugin - Juniper EX/QFX Swtich CloudStack Integration -
PDF
GKEで半年運用してみた
第20回 OpenStack勉強会 Neutron Deep Dive - DVR
OpenWrtによるサイト間IPsec接続
Opencontraildays2014dist 140514051248-phpapp01
Open contraildays2014
Deno の node 互換モードと ソケット
Serf / Consul 入門 ~仕事を楽しくしよう~
NGINX Ingress Controller on RedHat OpenShift.pdf
OpenStackネットワーキング管理者入門 - OpenStack最新情報セミナー 2014年8月
Lagopus + DockerのDPDK接続
Docker Machineを始めるには?
"Up" with vagrant and docker
Apache cloudstack4.0インストール
P2Pって何?
"Up" with vagrant and docker
Docker swarm mode 入門と ECS との比較
20140826 it pro_expo_rev2
NGINX Back to Basic 2 Part 2 (Japanese Webinar)
MSC2014_NetApp_Session
Juniper NetworkGuru Plugin - Juniper EX/QFX Swtich CloudStack Integration -
GKEで半年運用してみた
Ad

More from エピック・ゲームズ・ジャパン Epic Games Japan (20)

PDF
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
PDF
猫でも分かるUE4を使った VRコンテンツ開発 超入門編 2021
PDF
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
PDF
Unreal Engine 4.27 ノンゲーム向け新機能まとめ
PDF
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 1
PDF
UE4 Hair & Groomでのリアルタイムファーレンダリング (UE4 Character Art Dive Online)
PDF
UE4を使った映像制作 (UE4 Character Art Dive Online)
PDF
Hair Groom入門 (UE4 Character Art Dive Online)
PDF
UE4で”MetaHumanを使わずに”耳なし芳一になる10の方法 | UE4 Character Art Dive Online
PDF
『バランワンダーワールド』でのマルチプラットフォーム対応について UNREAL FEST EXTREME 2021 SUMMER
PDF
Visual Dataprepで建築データを美味しく下ごしらえ UNREAL FEST EXTREME 2021 SUMMER
PDF
Unreal Engineでのコンフィギュレーター制作と映像制作 UNREAL FEST EXTREME 2021 SUMMER
PDF
バレンシアガ『Afterworld: The Age of Tomorrow』の舞台裏 UNREAL FEST EXTREME 2021 SUMMER
PDF
『FINAL FANTASY VII REMAKE』におけるプロファイリングと最適化事例 UNREAL FEST EXTREME 2021 SUMMER
PDF
SAMURAI JACK開発事例:海外むけアクションゲームをオーソドックスに作ってみた UNREAL FEST EXTREME 2021 SUMMER
PDF
『ガールズ&パンツァー 最終章』第3話 アニメとゲームエンジンの融合(ジャングル完結編) UNREAL FEST EXTREME 2021 SUMMER
PDF
UE4を使用したバーチャルヒューマンの映像制作 UNREAL FEST EXTREME 2021 SUMMER
PDF
オンラインで同期した100体の巨大生物から地球を衛る方法 UNREAL FEST EXTREME 2021 SUMMER
PDF
MetaHumanサンプル解体新書 UNREAL FEST EXTREME 2021 SUMMER
PDF
Twinmotion 2021とAEC分野向けソリューションのご紹介
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
猫でも分かるUE4を使った VRコンテンツ開発 超入門編 2021
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 2
Unreal Engine 4.27 ノンゲーム向け新機能まとめ
Unreal Engine 5 早期アクセスの注目機能総おさらい Part 1
UE4 Hair & Groomでのリアルタイムファーレンダリング (UE4 Character Art Dive Online)
UE4を使った映像制作 (UE4 Character Art Dive Online)
Hair Groom入門 (UE4 Character Art Dive Online)
UE4で”MetaHumanを使わずに”耳なし芳一になる10の方法 | UE4 Character Art Dive Online
『バランワンダーワールド』でのマルチプラットフォーム対応について UNREAL FEST EXTREME 2021 SUMMER
Visual Dataprepで建築データを美味しく下ごしらえ UNREAL FEST EXTREME 2021 SUMMER
Unreal Engineでのコンフィギュレーター制作と映像制作 UNREAL FEST EXTREME 2021 SUMMER
バレンシアガ『Afterworld: The Age of Tomorrow』の舞台裏 UNREAL FEST EXTREME 2021 SUMMER
『FINAL FANTASY VII REMAKE』におけるプロファイリングと最適化事例 UNREAL FEST EXTREME 2021 SUMMER
SAMURAI JACK開発事例:海外むけアクションゲームをオーソドックスに作ってみた UNREAL FEST EXTREME 2021 SUMMER
『ガールズ&パンツァー 最終章』第3話 アニメとゲームエンジンの融合(ジャングル完結編) UNREAL FEST EXTREME 2021 SUMMER
UE4を使用したバーチャルヒューマンの映像制作 UNREAL FEST EXTREME 2021 SUMMER
オンラインで同期した100体の巨大生物から地球を衛る方法 UNREAL FEST EXTREME 2021 SUMMER
MetaHumanサンプル解体新書 UNREAL FEST EXTREME 2021 SUMMER
Twinmotion 2021とAEC分野向けソリューションのご紹介

UE4 MultiPlayer Online Deep Dive 基礎編2 -Traveling- (historia様ご講演) #ue4dd

  • 1. © historia Inc. #UE4DD Multiplayer Online Deep Dive - Traveling - historia Inc. 原 龍
  • 2. © historia Inc. #UE4DD Traveling ?  Listen Server を開始したり、Server に接続したり、 各プレイヤーの接続やレベル移動周りの話です  今回は OnlineSubsystem の Session 等は解説しません
  • 3. © historia Inc. #UE4DD Standalone Server Map A で Listen 開始Map A Map X Listen Server としてレベルを開始する → Listen 付き OpenLevel
  • 4. © historia Inc. #UE4DD Standalone Server Map A Client として接続リクエスト Client として Server に接続する → ClientTravel 接続させて Map X
  • 5. © historia Inc. #UE4DD Client Server Map A Map A Client として Server に接続する → ClientTravel いいよ 読み込むレベルを通知
  • 6. © historia Inc. #UE4DD Client Server Map B Map A Server がレベル移動する → ServerTravel 移動します 移動先のレベルを通知
  • 7. © historia Inc. #UE4DD Client Server Map B Map B Server がレベル移動する → ServerTravel 移動しました
  • 8. © historia Inc. #UE4DD Listen Server としてレベルを開始する
  • 9. © historia Inc. #UE4DD Standalone Server Map A で Listen 開始Map A Map X Listen Server としてレベルを開始する → Listen 付き OpenLevel
  • 10. © historia Inc. #UE4DD Listen Server としてレベルを開始する C++ /** Start Server */ UGameplayStatics::OpenLevel(GetWorld(), “LevelName", true, "listen");
  • 11. © historia Inc. #UE4DD Listen Server としてレベルを開始する Blueprint
  • 12. © historia Inc. #UE4DD Server UGameplayStatics::OpenLevel Listen Server 開始リクエスト UEngine::Browse UWorld::Listen UEngine::CreateNamedNetDriver UNetDriver::InitListen Listen Server 開始 NetDriver 作成
  • 13. © historia Inc. #UE4DD Client として Server に接続する
  • 14. © historia Inc. #UE4DD Standalone Server Map A Client として Server に接続する → ClientTravel 接続させて Map X Client Server Map A Map A いいよ
  • 15. © historia Inc. #UE4DD Client として Server に接続する C++ APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0); /** Start Client */ PlayerController->ClientTravel( “XXX.XXX.XXX.XXX”, // IP Address ETravelType::TRAVEL_Absolute, // トラベルタイプ false); // シームレストラベル有効フラグ
  • 16. © historia Inc. #UE4DD Client として Server に接続する Blueprint
  • 17. © historia Inc. #UE4DD UPendingNetGame::InitNetDriver UEngine::CreateNamedNetDriver UNetDriver::InitConnect APlayerController::ClientTravel Server 接続リクエスト NetDriver 作成 UEngine::Browse Client 接続開始
  • 18. © historia Inc. #UE4DD FNetControlMessage<NMT_Hello>::Send UNetDriver::InitConnect 接続開始 UConnection::CreateChannel ※CHTYPE_Control Client Control Channel 作成 Server へ Hello メッセージ送信
  • 19. © historia Inc. #UE4DD UPendingNetGame ?  Control Channel で Server に Hello メッセージして待っている間、 UPendingNetGame オブジェクトが Server からの返答待ち及び、 Server が Closed になっていないかどうかの監視を行う
  • 20. © historia Inc. #UE4DD Control Channel ?  C/S 間の接続の制御に利用されるチャンネル  UConnection 生成時に一つ生成される
  • 21. © historia Inc. #UE4DD ServerClient Hello ServerClient Challenge ServerClient Login ServerClient Welcome 1 2 3 4
  • 22. © historia Inc. #UE4DD Server UWorld::NotifyControlMessage Hello メッセージ受信 FNetworkVersion::IsNetworkCompatible FNetControlMessage<NMT_Challenge>::Send Client へ Challenge メッセージ送信 Network Version チェック
  • 23. © historia Inc. #UE4DD Network Version ?  C/S 間でアプリケーションの Network Version の照合を行うことができる  Server で Hello 受信時にバージョンチェックを行い、問題があれば Upgrade メッセージを Client に送信し、Client ではエラーとして処理する Server ver. 1.1 Client ver. 1.0 Hello Upgrade 更新して出直して来いこんにちは
  • 24. © historia Inc. #UE4DD Network Version ?  デフォルトだとバージョン情報は下記を繋げた文字列のハッシュ値 – Game Name – Project Version – ENGINE_NET_VERSION – Engine Network Protocol Version – Game Network Protocol Version
  • 25. © historia Inc. #UE4DD Network Version を制御するには ?  Game Network Protocol Version をアップデートに合わせて変更する – FNetworkVersion::GameCompatibleNetworkProtocolVersion  もしバージョン違いをある程度許容したい場合は下記をバインドして独自制御する /** Called in GetLocalNetworkVersion if bound */ DECLARE_DELEGATE_RetVal( uint32, FGetLocalNetworkVersionOverride ); static FGetLocalNetworkVersionOverride GetLocalNetworkVersionOverride; /** Called in IsNetworkCompatible if bound */ DECLARE_DELEGATE_RetVal_TwoParams( bool, FIsNetworkCompatibleOverride, uint32, uint32 ); static FIsNetworkCompatibleOverride IsNetworkCompatibleOverride; FNetworkVersion
  • 26. © historia Inc. #UE4DD UPendingNetGame::NotifyControlMessage Challenge メッセージ受信 ULocalPlayer::GetPreferredUniqueNetId FNetControlMessage<NMT_Login>::Send Server へ Login メッセージ送信 OnlineSubsystem から Net ID を取得 Client
  • 27. © historia Inc. #UE4DD Server UWorld::NotifyControlMessage Login メッセージ受信 AGameModeBase::PreLogin UWorld::WelcomPlayer ログイン前処理 AGameModeBase::GameWelcomPlayer FNetControlMessage<NMT_Welcome>::Send Client へ Welcome メッセージ
  • 28. © historia Inc. #UE4DD PreLogin でログイン許可判定  AGameModeBase::PreLogin では ErrorMessage を返すことができる  規定人数に達していたり、何らかの要因でログインさせたくない場合は ErrorMessage に何らかの文字を入れることで、 Client には Control Channel から Failure メッセージが飛ぶ ServerClient Login Failure お前はダメログインしたい
  • 29. © historia Inc. #UE4DD UPendingNetGame::NotifyControlMessage Welcome メッセージ受信 Map 名を受け取る UEngine::TickWorldTravel UEngine::LoadMap Map 読み込み Client UPendingNetGame::LoadMapCompleted FNetControlMessage<NMT_Join>::Send Server へ Join メッセージ送信
  • 30. © historia Inc. #UE4DD Server UWorld::NotifyControlMessage Join メッセージ受信 UWorld::SpawnPlayActor PlayerController をスポーン AGameModeBase::Login AGameModeBase::PostLogin ログイン受け入れ
  • 31. © historia Inc. #UE4DD ここまでの内容をまとめると
  • 32. © historia Inc. #UE4DD • AGameModeBase • UNetDriver • UNetDriver• UNetDriver Client 1 Server Client 2 • UNetConnection • UControlChannel Server / Client • UNetConnection • UControlChannel Server / Client
  • 33. © historia Inc. #UE4DD Server がレベル移動する
  • 34. © historia Inc. #UE4DD Client Server Map B Map A Server がレベル移動する → ServerTravel 移動します Client Server Map B Map B 移動しました
  • 35. © historia Inc. #UE4DD Server がレベル移動する C++ /** Start ServerTravel */ GetWorld()->ServerTravel(“LevelName”, false);
  • 36. © historia Inc. #UE4DD Server がレベル移動する Blueprint
  • 37. © historia Inc. #UE4DD Server UWorld::ServerTravel ServerTravel 開始 AGameModeBase::CanServerTravel AGameModeBase::ProcessServerTravel ServerTravel 可否判定 AGameModeBase::ProcessClientTravel NextURL 設定 (後に UEngine::Browse でレベル移動する) APlayerController::ClientTravel 各 Client で ClientTravel を実行 (Run on Owning Client & Reliable)
  • 38. © historia Inc. #UE4DD APlayerController::ClientTravel Server 接続リクエスト Client 以下、前述した ClientTravel の流れと同じ Control Channel を介してログイン処理を行う
  • 39. © historia Inc. #UE4DD つまり、ServerTravel でレベル移動を行うと、 移動する度に Server へのログイン処理が実行される
  • 40. © historia Inc. #UE4DD 接続を維持したままレベル移動を行いたい場合は? → SeamlessTravel を利用する
  • 41. © historia Inc. #UE4DD SeamlessTravel ?  レベルをストリーミングで読み込み、Transition Map を経由しながら GameMode 等の Actor を引き継いだままレベル遷移する事で、オーバーヘッドを小さくできる  非 Seamless な ServerTravel と違い、Client との接続は保持したまま BeforeMap AfterMapTransition Map
  • 42. © historia Inc. #UE4DD SeamlessTravel を有効にする public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=GameMode) uint32 bUseSeamlessTravel : 1; AGameModeBase
  • 43. © historia Inc. #UE4DD Transition Map ?  ワールドを保持したままレベル遷移するため、古いレベルがオンメモリのまま 新しいレベルが読み込まれる  つまり瞬間的に二つのレベルが共存するため、メモリに優しくない  そのため小さな Transition Map を間に挟むことで、古いレベルを解放してから 新しいレベルのロードが始まるように処理されている
  • 44. © historia Inc. #UE4DD Transition Map を設定する
  • 45. © historia Inc. #UE4DD Server AGameModeBase::ProcessServerTravel UWorld::SeamlessTravel NextURL は 設定しない (UEngine::Browse されない) FSeamlessTravelHander::StartTravel SeamlessTravel 開始 FSeamlessTravelHander::LoadPackageAsync レベルストリーミング開始
  • 46. © historia Inc. #UE4DD FSeamlessTravelHander ?  SeamlessTravel 時のシーケンス管理用オブジェクト  TransitionMap を LoadAsync して完了待ちを行い、完了したら古いレベルを PendingKill してから CollectGarbage する  TransitionMap への移行が完了したら、新しいレベルへの移行シーケンスを開始する
  • 47. © historia Inc. #UE4DD Server Client SeamlessTravel SeamlessTravel ServerTravel - PreClientTravel ClientTravel - PreClientTravel Client / Reliable Server / Reliable ServerNotifyLoadedWorld NotifyLoadedWorld PostSeamlessTravel NotifyLoadedWorld
  • 48. © historia Inc. #UE4DD Server Client SeamlessTravel SeamlessTravel ServerTravel - PreClientTravel ClientTravel - PreClientTravel ServerNotifyLoadedWorld NotifyLoadedWorld PostSeamlessTravel NotifyLoadedWorld 開始 / 終了のトリガー Client / Reliable Server / Reliable
  • 49. © historia Inc. #UE4DD SeamlessTravel 時に引き継がれるアクターは?  [Server] GameMode / GameState  [Server] 有効な PlayerState を持つ全ての Controller  [Server] 全ての PlayerController  [Server / Client] 各 Server / Client が所持する PlayerController
  • 50. © historia Inc. #UE4DD ゲーム都合で引き継ぐアクターを追加したい場合は?  下記関数をオーバーライドして ActorList に追加する – AGameModeBase  GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList) – APlayerController  GetSeamlessTravelActorList(bool bToEntry, TArray<class AActor*>& ActorList)
  • 51. © historia Inc. #UE4DD と、ドキュメントには記載があり、大体合ってるが…
  • 52. © historia Inc. #UE4DD SpawnPlayerController 新規に PlayerController を スポーンして Swap している
  • 53. © historia Inc. #UE4DD PlayerController で引き継がれるプロパティは?  Location, Rotation  保持する PlayerState の全プロパティ(コピーされる)  RemoteRole 等、Online 系のプロパティ
  • 54. © historia Inc. #UE4DD ゲーム都合で引き継ぐプロパティを追加したい場合は? /** Called when a PlayerController is swapped to a new one during seamless travel */ UFUNCTION(BlueprintImplementableEvent, Category=Game, meta=(DisplayName="OnSwapPlayerControllers")) void K2_OnSwapPlayerControllers(APlayerController* OldPC, APlayerController* NewPC); AGameModeBase イベント呼び出し時に 必要なものをコピーする
  • 55. © historia Inc. #UE4DD OnSwapPlayerControllers の注意点  PlayerController が Local or Remote で Swap タイミングが異なる – Local PlayerController は Swap -> BeginPlay の順番 – Remote PlayerController は BeginPlay -> Swap の順番  Swap が呼び出されるのは Server のみ
  • 56. © historia Inc. #UE4DD SeamlessTravel をデバッグする
  • 57. © historia Inc. #UE4DD SeamlessTravel をデバッグする時の注意点  PIE は現状だと非サポート  デバッグするためには Standalone で起動する必要がある – イテレーション速度の低下 – そもそもエディタからは複数プロセスで Standalone 起動はできない  game オプション付きで起動するバッチファイルを作るのがオススメ
  • 58. © historia Inc. #UE4DD Visual Studio でデバッグする  エディタもしくはバッチファイルから Standalone 起動した場合、 Visual Studio でデバッグしたいなら Attach to Process するしかない  デバッグする度に、検索窓も無いプロセス一覧から特定のプロセスを探して アタッチして…、というのは非常に面倒
  • 59. © historia Inc. #UE4DD UnrealVS を使ってコマンドラインに渡す引数を追加する [ProjectName] [起動したいMap] –game [その他オプション] と設定して Start Debugging すると、デバッグしながら起動できる 実行したコマンドラインオプションは履歴が残り、プルダウンで設定できるので便利
  • 60. © historia Inc. #UE4DD UnrealVS で楽にはなるが、それでも PIE 非対応は辛い… // NOTE - This is a temp check while we work on a long term fix // There are a few issues with seamless travel using single process PIE, so we're disabling that for now while working on a fix AGameModeBase::CanServerTravel SeamlessTravel + PIE は現状だといくつかのバグを抱えていて、 将来的にこれは解決される見込みとのことなので、今後に期待
  • 61. © historia Inc. #UE4DD まとめ  Server としてレベル移動する時、Client として Server に接続する 初回のレベル移動はブロッキングが発生する  C/S 間接続のキモは UControlChannel で、メッセージタイプも多くないので 何がサポートされているのかを最初に眺めてみると良い  SeamlessTravel はデバッグが辛いので早期改善を希望
  • 62. © historia Inc. #UE4DD まとめ  色々困ったら下記クラスの実装を追うと良い – UWorld – AGameModeBase – APlayerController – UNetConnection – UControlChannel – FSeamlessTravelHandler
  • 63. © historia Inc. #UE4DD ご清聴ありがとうございました historia Inc. 原 龍