UE4 MultiPlayer Online Deep Dive 基礎編1 -Getting Started- (historia様ご講演) #UE4DD

2.9K Views

July 04, 17

スライド概要

2017年7月2日に行われたライセンシー様向けMO勉強会の資料です。基礎編 @ (登壇者: historia 原龍さま)

profile-image

Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/

シェア

埋め込む »CMSなどでJSが使えない場合

各ページのテキスト
1.

Multiplayer Online Deep Dive - Getting Started historia Inc. 原 龍 © historia Inc. #UE4DD

2.

https://github.com/HogeTatu/UE4Plugin_WebApi © historia Inc. #UE4DD

3.

本日の Deep Dive のお題目 Multiplayer Online © historia Inc. #UE4DD

4.

Multiplayer Online (MO) 人数 プレイ時間 少人数(多くても30人程度) 短い(長くても60分程度) 求められるもの リアルタイム性が高い(低レイテンシ) ゲームデザイン • • • • アクション 格闘ゲーム FPS, TPS MOBA (Multiplayer Online Battle Arena) © historia Inc. #UE4DD

5.

本日の流れ 導入(オンライン機能概要) Dedicated Server Traveling RPC / Replicate TCP Plugin はじめに、機能概要と Traveling 周りをヒストリアからご説明 © historia Inc. #UE4DD

6.

本日の流れ 導入(オンライン機能概要) Dedicated Server Traveling RPC / Replicate TCP Plugin RPC / Replicate を中心に、バイキング様からご説明 © historia Inc. #UE4DD

7.

本日の流れ 導入(オンライン機能概要) Dedicated Server Traveling RPC / Replicate TCP Plugin Dedicated Server を中心に、ソレイユ様からご説明 © historia Inc. #UE4DD

8.

http://cedric-neukirchen.net/Downloads/Compendium/UE4_Network_Compendium_by_Cedric_eXi_Neukirchen.pdf 本日の内容は Cedric ‘eXi’ Neukirchen 様の資料を参考にさせて頂いています。 こちらも合わせてご確認頂けると、理解が進むと思われます。 © historia Inc. #UE4DD

9.

ネットワークモード © historia Inc. #UE4DD

10.

UE4 は Client-Server (C/S) モデル Server Client 1 Client 2 © historia Inc. ゲームプレイフローを制御 Client 3 #UE4DD

11.

Listen Server (プレイヤーの1人がサーバーを担当) Server Client 1 Client 2 © historia Inc. Client 3 #UE4DD

12.

Dedicated Server (専用のインスタンスがサーバーを担当) Server Client 1 Client 2 Client 3 © historia Inc. Client 4 #UE4DD

13.

同期処理 1. Replicate (プロパティ同期) © historia Inc. #UE4DD

14.
[beta]
Actor のプロパティを C/S 間で同期
C++
/** 同期するプロパティ */
UPROPERTY(Replicated)
int32 SampleProperty;

/** 同期するプロパティを ActorChannel に通知 */
void ASampleActor::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ASampleActor, SampleProperty);
}

© historia Inc.

#UE4DD

15.

Actor のプロパティを C/S 間で同期 Blueprint © historia Inc. #UE4DD

16.

Actor のプロパティを C/S 間で同期後、コールバック通知 C++ /** 同期するプロパティ */ UPROPERTY(ReplicatedUsing=OnRep_SampleProperty) int32 SampleProperty; /** プロパティ同期通知コールバック */ UFUNCTION() void OnRep_SampleProperty(); ※ GetLifetimeReplicatedProps はコールバックの有無で変更なし © historia Inc. #UE4DD

17.

Actor のプロパティを C/S 間で同期後、コールバック通知 Blueprint © historia Inc. #UE4DD

18.

Actor Channel ? ▪ C/S 間で Actor と SubObject を同期するための通信チャンネル ▪ Actor のスポーン情報を持ち、レプリケートされた Actor の生成 / 破棄を管理する ▪ 所有する FObjectReplicator がプロパティ同期と RPC を行う © historia Inc. #UE4DD

19.

Actor がレプリケートされる流れ Server Client Actor • • Actor • • • プロパティの差分抽出 リクエストされた RPC Actor Channel アクターの生成 プロパティの反映 RPC の実行 Actor Channel © historia Inc. #UE4DD

20.

GetLifetimeReplicatedProps の役割 ▪ FObjectReplicator がパケットレイアウトを決めるために、 同期するプロパティを判断する際に利用される ▪ 同期するプロパティを設定しつつ、同期される条件(≒タイミング)を 指定することも可能 © historia Inc. #UE4DD

21.
[beta]
Actor のプロパティを同期する条件を指定
C++
/** 同期するプロパティ */
UPROPERTY(Replicated)
int32 SampleProp;

/** 同期するプロパティを ActorChannel に通知 */
void ASampleActor::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(ASampleActor, SampleProp, COND_SkipOwner);
}

© historia Inc.

#UE4DD

22.

Actor のプロパティを同期する条件を指定 Blueprint © historia Inc. #UE4DD

23.

プロパティ同期条件一覧 ▪ COND_None ▪ COND_InitialOnly ▪ COND_OwnerOnly ▪ COND_SkipOwner ▪ COND_SimulatedOnly ▪ COND_AutonomousOnly ▪ COND_SimulatedOrPhysics ▪ 常時同期(条件なし) ▪ 初回同期もしくは Actor の所有者 初回同期のみ ▪ COND_SimulatedOnlyNoReplay Simulated のみ(リプレイ時は除く) Role=ROLE_AutonomousProxy のみ ▪ COND_ReplayOnly リプレイ時のみ Role=ROLE_SimulatedProxy のみ ▪ COND_ReplayOrOwner リプレイ時もしくは Actor の所有者 Actor の所有者以外 ▪ COND_Custom 条件をランタイムで変更できる ※詳しくは後述 Actor の所有者のみ ▪ COND_InitialOrOwner COND_SimulatedOrPhysicsNoReplay Simulated もしくは bRepPhysics のみ(リプレイ時は除く) Simulated もしくは bRepPhysics のみ COND_SkipReplay リプレイ時以外 © historia Inc. #UE4DD

24.

COND_Custom C++ /** PreReplication で同期する条件を指定 */ void ASampleActor::PreReplication( IRepChangedPropertyTracker& ChangedPropertyTracker) { Super::PreReplication(ChangedPropertyTracker); DOREPLIFETIME_ACTIVE_OVERRIDE( ASampleActor, SampleProp, bReplicateSampleProp); } © historia Inc. #UE4DD

25.

同期処理 2. RPC (Remote Procedure Call) © historia Inc. #UE4DD

26.

Multicast (Server / 全 Client で実行) C++ /** Multicast */ UFUNCTION(NetMulticast, unreliable) void Multicast_SampleEvent(); void ASampleActor::Multicast_SampleEvent_Implementation() { } © historia Inc. #UE4DD

27.

Multicast (Server / 全 Client で実行) Blueprint © historia Inc. #UE4DD

28.

Run on Owning Client (Actor を所有する Client で実行) C++ /** Run on Owning Client */ UFUNCTION(Client, unreliable) void Client_SampleEvent(); void ASampleActor::Client_SampleEvent_Implementation() { } © historia Inc. #UE4DD

29.

Run on Owning Client (Actor を所有する Client で実行) Blueprint © historia Inc. #UE4DD

30.

Run on Server (Server で実行) C++ /** Run on Server */ UFUNCTION(Server, unreliable, WithValidation) void Server_SampleEvent(); void ASampleActor::Server_SampleEvent_Implementation() { } bool ASampleActor::Server_SampleEvent_Validate() { return true; } © historia Inc. #UE4DD

31.

Run on Server (Server で実行) Blueprint © historia Inc. #UE4DD

32.

WithValidation ▪ RPC で呼び出される関数を実行する直前に検証用の関数を実行する ▪ 関数名は RPCFunctionName_Validate で戻り値は boolean ▪ 戻り値で false を返すと RPC で呼び出された関数は実行されない © historia Inc. #UE4DD

33.

Reliable ▪ RPC は UDP で通信する都合上、パケットの欠損や順序が不定になるといった ことが起こるため、確実に受信されてほしい処理には向いていない ▪ Reliable フラグを利用することで RPC 実行時に疎通確認を行い、 通信の信頼性を向上させる ことができる © historia Inc. #UE4DD

34.

Reliable C++ /** Run on Server */ UFUNCTION(Client, reliable, WithValidation) void Server_SampleEvent(); Blueprint © historia Inc. #UE4DD

35.

Actor の所有権 © historia Inc. #UE4DD

36.

ここはUE4のマルチプレイを理解する上で重要な部分です (ハマりやすい部分です) © historia Inc. #UE4DD

37.

Actor の所有権とは ▪ Server / Client は Actor に対して所有権を持つ ▪ AActor::Owner で所有権を持つかどうかを判断できる ▪ ただし Pawn の場合は APawn::IsLocallyControlled で判断する ▪ 所有権の有無によって、RPCの実行が制限されるケース が存在する © historia Inc. #UE4DD

38.

RPCの実行が制限されるケース (Server で実行した場合) Actor 所有者 Multicast Run on Server Run on Owning Client Client Server / 全 Client で実行 Server で実行 所有する Client で実行 Server Server / 全 Client で実行 Server で実行 Server で実行 © historia Inc. #UE4DD

39.

RPCの実行が制限されるケース (Client で実行した場合) Actor 所有者 Multicast Run on Server Run on Owning Client 自 Client 自 Client で実行 Server で実行 自 Client で実行 他 Client 自 Client で実行 実行されない 自 Client で実行 Server 自 Client で実行 実行されない 自 Client で実行 © historia Inc. #UE4DD

40.

RPC が実行されないケース – (1) Server Server が所有する Actor RPC 呼び出し Client 1 Client 2 © historia Inc. #UE4DD

41.

RPC が実行されないケース – (2) Server 他 Client が所有する Actor RPC 呼び出し Client 1 Client 2 © historia Inc. #UE4DD

42.

なぜ所有権は必要? 所有者以外が悪意を持って 不正に Actor を操作する事への対処 © historia Inc. #UE4DD

43.

所有権によるカテゴライズ ▪ Actor は全ての Server / Client にレプリケートされるわけではい ▪ Actor がどこにレプリケートされるかというカテゴライズは、 Actor のプロパティ設定を元に行われる © historia Inc. #UE4DD

44.

Server Only Server Client 1 ▪ サーバーのみに生成されるアクター ▪ GameMode など Client 2 © historia Inc. #UE4DD

45.

Server Only AServerOnlyActor::AServerOnlyActor() { // プレイヤーが持つコントロール権 Role = ROLE_Authority; // 他プレイヤーが持つコントロール権 RemoteRole = ROLE_None; // 同期対象フラグ bReplicates = false; // 所有権を持つクライアントのみに同期するフラグ bOnlyRelevantToOwner = false; } © historia Inc. #UE4DD

46.

Server & Client ▪ Server サーバーと全てのクライアントに 生成されるアクター ▪ GameState, PlayerState など ▪ ほとんどのアクターはこの設定で サーバーが生成し、レプリケートされる Client 1 Client 2 © historia Inc. #UE4DD

47.

Server & Client AServerClientActor::AServerClientActor() { // プレイヤーが持つコントロール権 Role = ROLE_Authority; // 他プレイヤーが持つコントロール権 RemoteRole = ROLE_SimulatedProxy; // 同期対象フラグ bReplicates = true; // 所有権を持つクライアントのみに同期するフラグ bOnlyRelevantToOwner = false; } © historia Inc. #UE4DD

48.

Server & Client (所有者) ▪ Server サーバーと所有するクライアントのみに 生成されるアクター ▪ PlayerController, Possess している Pawn など Client 1 Client 2 © historia Inc. #UE4DD

49.

Server & Client (所有者) AServerOwningClientActor::AServerOwningClientActor() { // プレイヤーが持つコントロール権 Role = ROLE_Authority; // 他プレイヤーが持つコントロール権 RemoteRole = ROLE_SimulatedProxy; // 同期対象フラグ bReplicates = true; // 所有権を持つクライアントのみに同期するフラグ bOnlyRelevantToOwner = true; } © historia Inc. #UE4DD

50.

OnlineSubsystem © historia Inc. #UE4DD

51.

各種SDK OnlineSubsystem ゲーム プラットフォームの APIを抽象化 • • • • • • • ログイン セッション管理 マッチング 実績 ランキング チャット ストア(課金) etc... © historia Inc. Steam PS4 Oculus Google Amazon Facebook #UE4DD

52.

OnlineSubsystem の設計 ▪ 各プラットフォームは機能別に定義されたインターフェースを継承したクラスを実装する ▪ インターフェースは IOnline[機能名] で用意されている – ex. IOnlineAchievements ▪ 各プラットフォームは FOnline[機能名][プラットフォーム名] で実装する – ex. FOnlineAchievementSteam © historia Inc. #UE4DD

53.

OnlineSubsystem で機能が足りていなかった場合は? ▪ 必要なインターフェースを継承しつつ、足りていない機能のクラスを新規作成する ▪ IOnlineSubsystem を継承しながら、プラットフォーム別に FOnlineSubsystem[プラットフォーム] が実装されているので、 各機能の実装を取得する Get[機能名]Interface で追加した機能の リファレンスを返すようにする © historia Inc. #UE4DD

54.

© historia Inc. #UE4DD

55.

ここからは開発フローについて © historia Inc. #UE4DD

56.

ネットワーク対応ゲームの基本的なデプロイフロー QA Development ステージング サーバー 作業PC Release 開発サーバー 公開サーバー © historia Inc. #UE4DD

57.

作業PC(ローカル) QA Development ステージング サーバー 作業PC Release 開発サーバー 公開サーバー © historia Inc. #UE4DD

58.

ローカルでのマルチプレイプレビュー 1. PIE 起動 © historia Inc. #UE4DD

59.

© historia Inc. #UE4DD

60.

© historia Inc. #UE4DD

61.

PIE 起動時に自動でマッチングされた状態にする Editor Preferences -> Level Editor -> Play -> Multiplayer Options -> Auto Connect To Server 単体のレベルでマルチプレイのデバッグを行うときに有効 © historia Inc. #UE4DD

62.

Auto Connect To Server の注意点 ▪ 簡易的に Server / Client の設定だけ行ってプレビューを行っている ▪ つまり C/S 間で正式な手続き(Control Channel でのメッセージング) を行っていないため、レベル移動を行ってしまうと正常な結果にならない © historia Inc. #UE4DD

63.

ローカルでのマルチプレイプレビュー 2. –game オプションで起動 © historia Inc. #UE4DD

64.

UE4Editor.exe に uproject を指定して -game オプションを付けて起動すると、 Cook 無しスタンドアロン実行 が可能 © historia Inc. #UE4DD

65.

起動バッチを作ると便利 @echo off set set set set set EDITOR_PATH=..¥Engine¥Binaries¥Win64¥UE4Editor.exe UPROJECT_NAME=MultiplayerOnlineDD.uproject SERVER_MAP_NAME=/Game/DeepDive/Maps/OpenUrl/OpenUrlServer CLIENT_MAP_NAME=/Game/DeepDive/Maps/OpenUrl/OpenUrlClient LAUNCH_PARAM=-game -ResX=640 -ResY=360 -WINDOWED start %EDITOR_PATH% %UPROJECT_NAME% %SERVER_MAP_NAME% %LAUNCH_PARAM% ^ -WinX=100 -WinY=100 -log -ConsoleX=100 -ConsoleY=500 start %EDITOR_PATH% %UPROJECT_NAME% %CLIENT_MAP_NAME% %LAUNCH_PARAM% ^ -WinX=800 -WinY=100 exit © historia Inc. #UE4DD

66.

© historia Inc. #UE4DD

67.

PIE 起動でのプレビューはあくまで単一プロセスでの実行で ダミー的に処理されている部分があるため、 デプロイ前には一度デバッグしておいた方が良い © historia Inc. #UE4DD

68.

パケットシミュレーション © historia Inc. #UE4DD

69.

ローカルプレビューではパケットの遅延等が全く発生せず、 実際にマシン間で通信する際に 意図した挙動にならないといった事が起こりえます © historia Inc. #UE4DD

70.

ローカルプレビュー時にこのような状態を再現するため、 エミュレート用の各種デバッグコマンドが用意されています © historia Inc. #UE4DD

71.

Net PktLoss=[Int] ▪ 確率でパケットを送信しない(消失シミュレーション) ▪ 単位は 0 – 100 % © historia Inc. #UE4DD

72.

Net PktOrder=[Boolean] ▪ パケットをバッファリングして送信順序をランダムにする ▪ 単位は 0 – 1 © historia Inc. #UE4DD

73.

Net PktLag=[Int] ▪ パケット送信時に遅延を発生させる(固定値) ▪ 単位はミリ秒 © historia Inc. #UE4DD

74.

Net PktLagVariance=[Int] ▪ パケット送信時に遅延を発生させる(範囲ランダム値) ▪ 単位は ± ミリ秒 © historia Inc. #UE4DD

75.

B.SendTime = FPlatformTime::Seconds() + (double(PacketSimulationSettings.PktLag) + 2.0f * (FMath::FRand() - 0.5f) * double(PacketSimulationSettings.PktLagVariance))/ 1000.f; © historia Inc. #UE4DD

76.

Net PktDup=[Int] ▪ パケット送信時に確率で2回送信する(重複させる) ▪ 単位は 0 – 100 % © historia Inc. #UE4DD

77.

この辺の実装は UNetConnection::FlushNet © historia Inc. #UE4DD

78.

RPC のデバッグ © historia Inc. #UE4DD

79.

net.RPC.Debug [Boolean] RPC 実行時のログを Warning で出力する 有効にした状態で LogNet でフィルターを設定すると Traveling や Replicate の流れがよく見える © historia Inc. #UE4DD

80.

ネットワークプロファイラ © historia Inc. #UE4DD

81.

ネットワークプロファイラ ▪ Replication, RPC に関するプロファイラ ▪ 帯域のボトルネックを調査する時に有用 ▪ Actor / Property / RPC でフィルタリングすることも可能 © historia Inc. #UE4DD

82.

ネットワークプロファイラ ▪ netprofile enable/disable でプロファイリング状態を切り替える ▪ プロファイリング結果を確認するためには下記パスからツールを起動する – /Engine/Binaries/DotNET/NetworkProfiler.exe ▪ プロファイリング結果は下記ディレクトリに保存されている – /ProjectRoot/Saved/Profiling © historia Inc. #UE4DD

83.

© historia Inc. #UE4DD

84.

https://docs.unrealengine.com/latest/JPN/Gameplay/Tools/NetworkProfiler/index.html © historia Inc. #UE4DD

85.

開発サーバー QA Development ステージング サーバー 作業PC Release 開発サーバー 公開サーバー © historia Inc. #UE4DD

86.

パッケージ生成 © historia Inc. #UE4DD

87.

UE4 では同一プロジェクトから各種パッケージを生成 UE4 Solution • Windows Client • Windows Server UE4 Project • PS4 Client • Linux Server Game Project etc ... © historia Inc. #UE4DD

88.

Build Configuration ビルド名 [empty] ビルド概要 ビルドルールを指定するファイル スタンドアロンゲーム実行用のビルド ProjectName.Target.cs Editor エディタ実行用のビルド ProjectNameEditor.Target.cs Client マルチプレイゲームにおけるクライアント用のビルド ProjectNameClient.Target.cs Server マルチプレイゲームにおけるサーバー用のビルド ProjectNameServer.Target.cs © historia Inc. #UE4DD

89.

© historia Inc. #UE4DD

90.

© historia Inc. #UE4DD

91.

ビルドジョブセットからまとめて各種ビルドを実行する Batch Builder (UnrealVS 拡張) が便利 © historia Inc. #UE4DD

92.

Batch Builder はこのボタンから起動する © historia Inc. #UE4DD

93.

https://docs.unrealengine.com/latest/JPN/Programming/Development/VisualStudioSetup/UnrealVS/index.html © historia Inc. #UE4DD

94.

Client / Server ビルドで謎のコンパイルエラーが…? Client / Server ビルドは、ランチャーからインストールしたエンジンだとビルドできない仕様 (ProjectName.sln ではなく、UE4.sln からのみビルド可能) © historia Inc. #UE4DD

95.

Cook は ProjectLauncher から行うと 複数パッケージを同時に生成できる © historia Inc. #UE4DD

96.

Linux クロスコンパイル © historia Inc. #UE4DD

97.

Linux クロスコンパイル未使用時 Windows 開発マシン Linux 開発サーバー • エディタで開発 • Linux Server ビルド • Windows Client ビルド • サーバー上でテスト • Windows Server ビルド デプロイ • ローカルテスト © historia Inc. #UE4DD

98.

Linux クロスコンパイル未使用時 Windows 開発マシン Linux 開発サーバー • エディタで開発 • Linux Server ビルド • Windows Client ビルド • サーバー上でテスト • Windows Server ビルド デプロイ • ローカルテスト ビルドエラーで手戻りの可能性! © historia Inc. #UE4DD

99.

Linux クロスコンパイル使用時 Windows 開発マシン Linux 開発サーバー • エディタで開発 • サーバー上でテスト • Windows Client ビルド • Windows Server ビルド デプロイ • ローカルテスト • Linux Server ビルド デプロイ先でのエラーを防ぐ © historia Inc. #UE4DD

100.

https://docs.unrealengine.com/latest/JPN/Platforms/Linux/GettingStarted/index.html © historia Inc. #UE4DD

101.

Linux クロスコンパイル時の注意点 ▪ 基本的には使用するUE4のバージョンに合わせたツールチェーンのダウンロードと、 環境変数の設定のみ ▪ 複数のUE4プロジェクトが混在していて環境変数を汚染したくない場合、 LINUX_MULTIARCH_ROOT を検索して置き換えることで対応は可能 (DedicatedServer を選択する以上、自ずとエンジンはソースコードビルドになるので・・・) © historia Inc. #UE4DD

102.

まとめ ▪ MO ゲーム制作のための機能は一通り揃っている印象 ▪ ただしブラックボックスな部分が多く、実はできるのに知られていない機能や ini 設定、コンソールコマンドが用意されていたりする ▪ 実際の運用時には NetworkProfiler で細かく使用帯域を見ていく必要がある © historia Inc. #UE4DD